 
 /**
 
 Version 0.13, aavenwedde@demandware.de [AA]
 Date: 03/2009
 
 Library script to exchanges a part (or several parts) of an html document dynamically (with an asynchronous request).
 Optimized for lean and easy use.
 
 This script is supporting 'unobstrusive' javascript DOM manipulations, but still keeping 
 full event flow control with defined patterns at html source code.
 
 Motivation: Provide an easy and fast way to 'ajaxify' requests without maintaining
 wide-spreaded or hard to customize parts of code.

 Could be used to 'ajaxify' legacy-applications also.
 
 -----
 
 How to use:
 
 At any '<a>' tag at html document, add an attribute 'rel' ('relation') to invoke this
 functionality.
 
 The 'rel' attribute must follow this guidlines to work as expected:
 rel="ajax_[divId]_[callback]". 
 [callback] is optional for advanced features.
 
 -----
 
 Example: (Those html-comments need to be remain intact for use, the 
 jQuery version may vary).
 
 
<script type="text/javascript" src="[path]/jquery-1.3.2.min.js"/>
<script type="text/javascript" src="[path]/ajaxhref.js"/>

 
..

<script type="text/javascript">
  // params are: onstart|onend
  function callback(hook , param1) {
    if (hook == "onstart") {
      // do something onstart, i.e. fadeOut
    }
    else if (hook == "onend") {
      // do something onend, i.e. fadeIn
    }   
  }
</script>
.. 

  <div id="myId">
   <!-- Following comments are mandatory and must not removed/don't use spaces at those comments, please. -->
   <!--start_myId-->
    Old content part1 to be replaced with new one by click onto link below.
   <!--end_myId-->
  </div>
  ..
  <div id="myId2">
   <!-- Following comments are mandatory and must not removed/don't use spaces at those comments, please. -->
   <!--start_myId2-->
    Old content part2 to be replaced with new one by click onto link below.
   <!--end_myId2-->
  </div>

 <a href="#" rel="ajax_myId_callback">A link to replace all content(s) specified above.</a>
 
 ..
 Advanced (BETA):
 
 Within the global AJAXHREF_EXCHANGE_HASH it is possible to guide-trough any javascript-objects
 to the callback function.
 Here: Used for url modifications only, to be extended.
 
 Prerequisites:
  
  jQuery is needed for parts of this functionality.
  
  Hints:
  A simple callback can be added to the 'rel' flag, to trigger advanced features
  (slide, fade..).
  
  TODO: Wrap this into own namespace.
  
 */


// New: Cache alredy done requests for performance:

 var ajaxhref_requestCache = [];

// Globally used exchange hash for this library.
// Intended i.e. to hold objects with short-lifecycle time (i.e. during pending requests) only.
// No automatic kind of 'garbage collection' yet.

 var AJAXHREF_EXCHANGE_HASH = [];

// On load event trigger:
 
 jQuery(document).ready(function() {
    		
    		ajaxhref_attachEvents();
    		
		});
	 
	   
	   function ajaxhref_attachEvents() {
	   	
	   	 // go through all anchors at the document
	   	 jQuery("a").each(function () {
	   		// Create a jQuery object of the anchor:
	   		$this = jQuery(this);
	   		var rel = $this.attr("rel");
	   		// Check if the rel attributes starts with ajax
	   		if(rel.match(/^ajax_/)) {
	   			
	   			var link = $this.text();
	   			// if there is anything on the click handler
	   			// delete it
	   			$this.unbind("click");
	   			// alert($this.attr("rel"));
	   			
	   			// The function called on click:
	   			
	   			$this.click(function(e){ 
		          //tags[i].addEventListener ("click" , clickHandle,false);
		          var href = jQuery(this).attr('href');

		          $this = jQuery(this);
		          
		          
		          
		          // Split the 'rel' attribute to get meta informations:
		          var s = [];
		          var s = $this.attr("rel").split("_");
		          if (s[0] == "ajax") {
		            // dispatch/display contents:
		            ajaxhref_contentDisp(href , s[1] , s[2]);
		          }
		          /*
		          if($this.attr("rel").match(/ajax_(\w*?)_(\w*?)/g)) {
		              alert(RegExp.$3);
		              ajaxhref_contentDisp(href , RegExp.$1 , RegExp.$2);
		          }
		          else {
		            //alert('nothing found');
		          }
		          */
		          // Skip default href link.
		          return false;
		          //alert(href);
		        });
	   		}
	   	});
	   }
	   
	   
	   // Get new contents defined by url and parse all required parts.
	   // The result is a text-response, so DOM methods are not available here.
	   // Do this job by parsing the comment-flags.
	   // TODO: Try to parse the html text response (possible, but: performance may be low).
	   
	   function ajaxhref_contentDisp(url , id , call) {
        
	        // Try to call onstart hook:
	        
	        // 'isCachedRequest' is a string, because of used 'eval':
	        var isCachedRequest = "no";
	        
	        AJAXHREF_EXCHANGE_HASH['url'] = url;
	        
	        if (ajaxhref_requestCache[url]) {
	          isCachedRequest = "yes";
	        }
	        
	        // Call callback function:
	        try {
	          eval(call + "('onstart','"+isCachedRequest+"')");
	        }
	        catch(e) {
	          
	          alert("Callback function: '" + call + "' is not defined (called at ajaxhref.js) or contains errors.\n Errormessage: '" + e + "'");
	        }
			
			url = AJAXHREF_EXCHANGE_HASH['url'];
	        
	        if (isCachedRequest == "yes") {
	           
	           ajaxhref_success(ajaxhref_requestCache[url] , id , call);
	        }
	        else {
	            jQuery.ajax({
	        
		        url : url,
		        success : function (data) {
		          // Put this response into cache:
		          ajaxhref_requestCache[url] = data;
		          // Render content parts:
		          ajaxhref_success(data , id , call);
		          
		           }
		        });
	        }
	       
    	}
	    
	    
	    
	    function ajaxhref_success(data , id ,  call) {
	       
	       // Filter data:
	       //if (data.match(/<!--start_(\w*?)_(\w*?)-->((.|\n|\r)*?)<!--end_(\w*?)_(\w*?)-->/gm)) {
	          
	          var ajaxContentParts = [];
	          //if (data.match(/<!--start_(\w*?)-->((.|\n|\r)*?)<!--end_\w*?-->/m)) {
	          
	          var commentTags = [];
	          var commentIds = [];
	          
	          commentTags = data.match(/<!--start_.*?-->/g);
	          //alert(commentTags);
	          
	          
	          if (commentTags) {
	            for (var i =0;i< commentTags.length;i++) {
	                  
	              var startcomment = commentTags[i];
	              //alert(startcomment);
	              // substr: from , range
	              commentIds[i] = startcomment.substring( 10 , startcomment.length-3);
	              //alert(commentIds[i]);
	              var endcomment = "<!--end_" + commentIds[i] + "-->";
	              //alert(endcomment);
	              
	              var start = data.indexOf(startcomment) + startcomment.length;
	              var end = data.indexOf(endcomment);
	              var text = data.substring(start,end);
	              //alert(text);
	              ajaxContentParts[commentIds[i]] = text;
	              //alert(start);alert(end);
	              
	            }
	          }
	          
	          
	           
	           for (key in ajaxContentParts) {
	             
	              //alert('Part: ' + key+ ' : '  + ajaxContentParts[key]);
	              
	              if (key.length > 1) {
	                
	                //jQuery("#"+key).html(ajaxContentParts[key]);
	                // Pure javascript is working best here:
	                try {
	                  
	                  document.getElementById(key).innerHTML = ajaxContentParts[key];
	                }
	                catch(e) {
	                  //alert("(ajaxhref) key: " + key + " not found.");
	                }
	                
	              }
	              
	           }
	           
	           // Re-attach events (because those are lost after dynamic update ):
	           ajaxhref_attachEvents();
	           
	           // Call the 'onend' hook:
	           eval(call + "('onend')");
	    }
	   
	  
	  