var dc = {
  store: {},
  output: '',
  toAppend: {},
  compatFunc: false,
  init: function(){
    YAHOO.util.Event.addListener('dc', 'submit', dc.insertHTML);    
  },
  trim: function(str){
    return str.replace(/^\s+|\s+$/g,'');
  },
  insertHTML: function(e){
    // Clear output textarea
    YAHOO.util.Dom.get('domoutput').value = '';
    YAHOO.util.Dom.get('toappend').value = '';
    
    // Reset counter and output object
    dc.store = null;
    dc.store = {};
    dc.toAppend = null;
    dc.toAppend = [];
    dc.compatFunc = false;
    dc.output = '';
    
    YAHOO.util.Dom.get('labdcfunc').style.display = "none";
    YAHOO.util.Dom.get('dcfunc').style.display = "none";
    
    var inp = YAHOO.util.Dom.get('htmlinput').value;
    if (inp.replace(/^\s+/,'')  != ''){    
      var m = YAHOO.util.Dom.get('dcContainer');
      m.innerHTML = inp;  
      dc.followTree(m);
    } else {
      alert('Please enter some Text');
    }
    YAHOO.util.Event.stopEvent(e);
  },
  
  // Straight out of the the YUI DOM's private functions.
  toCamel: function(property) {
     var convert = function(prop) {
        var test = /(-[a-z])/i.exec(prop);
        return prop.replace(RegExp.$1, RegExp.$1.substr(1).toUpperCase());
     };
     while(property.indexOf('-') > -1) {
        property = convert(property);
     }
     return property;
  },
  
   
  followTree: function(el){
    var elc = el.childNodes;
    for (var i = 0, j= elc.length; i<j; i++){  
      var av    = '';      
      var nt    = elc[i].nodeType;
      var nn    = (nt == 1) ? elc[i].nodeName : 'txt';
      var nv    = (nt == 1) ? elc[i].nodeValue : elc[i].nodeValue.replace(/^\n?\s+/,'');
      
      var pn    = elc[i].parentNode;
      var pnn   = pn.nodeName; 
      
      var dcc = YAHOO.util.Dom.get('dcContainer');
      var ptags = dcc.getElementsByTagName(pnn);
      
      // Find Parent Correctly by checking the nodes with the same tag      
      if (ptags && pn.id != 'dcContainer'){
        for(g=0,h=ptags.length; g<h; g++){
          if (ptags[g] == pn ){
            pvr = pnn.toLowerCase()+(g+1);
            break;
          }
        }
      }else{
        pvr = null;
      }
          
      var attr  = elc[i].attributes; 
      // init store for this element
      if (!dc.store[nn]) dc.store[nn] = [];
      var vr = nn.toLowerCase()+(dc.store[nn].length+1);
      // Store element details for later (setting true as a default value.)
      if (nt!=3 && nv!='') dc.store[nn][dc.store[nn].length] = true;             
      switch(nt){
        // ELEMENT
        case 1:
          // Create Element
          if (elc[i].hasAttribute("name")) {
            dc.output += "var "+vr+"=ce('"+nn+"','"+elc[i].getAttribute('name')+"');\n";  
            dc.compatFunc = true;   
          }else{  
            dc.output += "var "+vr+"=document.createElement('"+nn+"');\n";      
          }
          // Build Attributes              
          if (attr){
            for (k=0,l=attr.length; k<l; k++){  
              if (elc[i].attributes[k].nodeName.toLowerCase() == 'name') continue;
              av = elc[i].attributes[k].nodeValue.replace(/'|&apos;/g, "\\'");  // Escape quotes
              av = av.replace(/\s+^/mg, "\\n");                                 // Escape carriage return
              
              switch(elc[i].attributes[k].nodeName.toLowerCase()){
                case 'class':
                  dc.output +=  vr+".className='"+av+"';\n";   
                break;
                case 'style':
                  
                  var sty = av.split(/[:;]/); 
                  if(sty){
                    for(p=0,q=sty.length; (p+2)<q; p=p+2){
                      
                      var styleProp = dc.trim(sty[p]);
                      styleProp = (styleProp.indexOf('-') > -1) ? dc.toCamel(styleProp) : styleProp; 
                      if (styleProp == 'float') styleProp = 'cssFloat';
                      
                      var styleVal = dc.trim(sty[p+1]);
                      styleVal = styleVal.replace(';','');
                      
                      dc.output += vr+'.style.'+styleProp+'="'+styleVal+'";\n';
                    }
                  }
                break;
                default:
                  dc.output +=  vr+".setAttribute('"+elc[i].attributes[k].nodeName+"','"+av+"');\n";   
                break;
              }   
            }
          }
          
          // Build object of nodes that will need to be appended
          if (elc[i].parentNode.id == 'dcContainer') dc.toAppend[vr] = true;
          
          break;
        // TEXTNODE  
        case 3:
          if (nv == '') continue;  
          nv = nv.replace(/'|&apos;/g, "\\'");                                  // Escape quotes
          nv = nv.replace(/\s+^/mg, "\\n");                                     // Escape carriage returns          
          dc.output += "var "+vr+"=document.createTextNode('"+nv+"');\n";
          break;
      }
      if (vr && pvr) {
        dc.output += pvr+".appendChild("+vr+");\n";
      }
      // Recurse
      dc.followTree(elc[i]);
    }  
    // Present DOM output
    YAHOO.util.Dom.get('domoutput').value = dc.output;    
    
    // Show nodes that need to be appended.
    var tapp = '';
    // Loop through object 
    for (prop in dc.toAppend) {
      if (dc.toAppend[prop] === true) {
        tapp +=  prop+'\n';
      }
    }
    
    YAHOO.util.Dom.get('toappend').value = tapp; 
    
    if (dc.compatFunc === true){
      YAHOO.util.Dom.get('labdcfunc').style.display = "block";
      YAHOO.util.Dom.get('dcfunc').style.display = "block";
    }   
    
  }
};
YAHOO.util.Event.addListener(window, 'load', dc.init);
