/*!
 * jQuery htmlDoc "fixer" - v0.2pre - 12/15/2010
 * http://benalman.com/projects/jquery-misc-plugins/
 * 
 * Copyright (c) 2010 "Cowboy" Ben Alman
 * Dual licensed under the MIT and GPL licenses.
 * http://benalman.com/about/license/
 */

(function($, jQuery){
  
  var // RegExp that matches opening and closing HTML, HEAD, BODY, SCRIPT, STYLE, LINK tags.
      // $1 = slash, $2 = tag name, $3 = attributes
      rtag = /<(\/?)(html|head|body|script|style|link)(\s+[^>]*)?>/ig;
  
  $.htmlDoc = function( str ) {
    var 
        counter = 0,

        // The same elements but replaced with div tags and some attributes added.
        elems_replaced = {},
        
        // Input HTML string, parsed to include placeholder DIVs.
        parsed,

        // Unique id prefix for selecting placeholder elements.
        prefix = 'ajaxed_hd' + +new Date(),
        
        // A node under which a temporary DOM tree will be constructed.
        root;
    
    // Replace HTML, HEAD, BODY, SCRIPT, STYLE, LINK[rel="stylesheet"] tags with DIV placeholders.
    parsed = str.replace( rtag, function( tag, slash, name, attrs ) {
      
      var 
          // Temporary objects in which to hold attributes.
          obj = {},
          attrs_obj = {},

          closing_div = '';

      // If this is an opening tag...
      if ( !slash ) {

        // If the original tag had attributes, create a temporary div with
        // those attributes. Then, copy each attribute from the temporary div
        // over to the temporary object.
        if ( attrs ) {
          attrs = $.trim(attrs);
          $.each( $( '<div ' + attrs + '/>' )[0].attributes, function(i,v){
            obj[ v.name ] = v.value;
            attrs_obj[ v.name ] = v.value;
          });
        }

        // Ignore LINK[rel!="stylesheet"] elements
        if (/link/i.test(name) && ! /stylesheet/i.test(obj['rel'])) {
            return tag;
        }

        // Add closing div for LINK[rel=stylesheet] placeholder
        if (/link/i.test(name) && /stylesheet/i.test(obj['rel'])) {
            closing_div = '</div>';
        }
       
        counter += 1;
        var id = prefix + counter;

        var original_element = $('<' + name + '/>').attr(obj);

        tag = '<' + name + ' ' + attrs + '>';

        name = name.toLowerCase()

        obj['data-ajaxed-element'] = name;
        obj['data-ajaxed-id'] = id;
        /*if (obj['class']) {
            obj['class'] += ' ajaxed-css-hide';
        } else {
            obj['class'] = 'ajaxed-css-hide';
        }*/

        obj['data-ajaxed-tag'] = encodeURIComponent(tag);

        var div_element = $('<div/>').attr(obj);

        var ob = { div_element: div_element, original_element: original_element, id: id, 'name': name, attrs: attrs_obj, tag: tag };
        elems_replaced[id] = ob;
      } else {
          if (/\-\-$/.test(attrs))
          {
              return tag;
          }
      }
      
      // A placeholder div with a unique id replaces the intended element's
      // tag in the parsed HTML string.
      return '<' + slash + 'div'
        + ( slash ? '' : ' id="' + id + '"'  ) + '>' + closing_div;
    });

      // Create the root node and append the parsed, place-held HTML.
      root = $('<div/>').html( parsed );

      // Replace each placeholder element with its intended element.
      $.each( elems_replaced, function(key, v){
        var dom_element = root.find( '#' + key );
        var h = dom_element.html();

        if (h) {
            h = h.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
        }

        if (v.name == 'script' || v.name == 'style' || v.name == 'link') {
        //if (true) {
            //dom_element.before( v.div_element.html(dom_element.contents()) );
            
            dom_element.before( v.div_element.html(h) );
            var closing_tag = v.name == 'link' ? '' : '</' + v.name + '>';
            //elems_replaced[key].html = v.tag + h + closing_tag;
            elems_replaced[key].html = h;
        } else {
            dom_element.before( v.original_element.html(h) );
            //elems_replaced[key] = undefined
        }
        dom_element.remove();
      });

      // Return the topmost intended element(s), sans text nodes.
      return [ root.children(), elems_replaced ];
    //}
    
    // No placeholder elements were necessary, so just return a normal
    // jQuery-parsed HTML string.
    //return $(str);
  };
  
})(ajaxed_jQuery, ajaxed_jQuery);

