﻿// Template utility functions...

function cloneElement(referenceEl, parentEl, newID) {
    var nodeName = referenceEl.nodeName;
    // Don't try to copy '#text' etc
    if (nodeName.indexOf('#') == -1) {            
        // Clear any event handlers on the reference element before copying (** THIS WAS THE KEY **)
        $clearHandlers(referenceEl);

        var newEl = referenceEl.cloneNode(false);
        if (referenceEl.id) {
            newEl.id = referenceEl.id + "_" + newID;        
        }
        // Remove any associated CC
        if (newEl.control) {
            newEl.control = undefined;
        }
        
        parentEl.appendChild(newEl);
        
        // Recursive call
        for(var i = 0; i < referenceEl.childNodes.length; i++) {
            cloneElement(referenceEl.childNodes[i], newEl, newID);
        }
    } else {        
        // If it's #text etc, copy the node value        
        var newEl = referenceEl.cloneNode(false);
        parentEl.appendChild(newEl);        
    }
    
}

// May be possible to simplify this using 'referenceEl.cloneNode()'    
function cloneElementCCs(referenceEl, newID, customFn) {
    var nodeName = referenceEl.nodeName;
    
   /*
    Here, we are going to need to recurse down through the elements.
    Should this be down through the reference elements or the new
    elements.
    Perhaps it's okay to go down through the reference elements
    because when we find an element which has a CC, it must
    have an id, so we can at that point work out what the id of
    the new element must be and find it.        
    */

    // Should look for an attached client component and clone here
    if (referenceEl.id && $find(referenceEl.id)) {
        var referenceCC = $find(referenceEl.id);
        var refType = Object.getType(referenceCC);
        
        var newEl = $get(referenceEl.id + "_" + newID);
        
        // Need to create the control 'manually'
        // so we can copy properties before initialising
        // (or we could put them in an array, but I think
        // this is easier)

        var newCC = new refType(newEl);  // Manual $create
        // Copy any properties that are not currently defined across
        // (except events)
        for(var ccp in referenceCC) {                              // Check it has a value
            if (typeof(newCC[ccp]) == 'undefined' && ccp != '_events' && referenceCC[ccp]) {
                            
                // If it's an element reference, resolve to the
                // correct cloned element
                if (referenceCC[ccp].nodeName) {  // IS HTML ELEMENT
                    newCC[ccp] = $get(referenceCC[ccp].id + "_" + newID);   // V------ Not sure why this check doesn't work
                } else if (referenceCC[ccp]._element) { // instanceof Sys.Component) // IS COMPONENT PROPERTY
                    // Set the reference to the component in the item instance
                    newCC[ccp] = $find(referenceCC[ccp].get_id() + "_" + newID);
                } else {
                    newCC[ccp] = referenceCC[ccp];
                }                    
            }
        }
        newCC.initialize();  // Manual $create
        Sys.Application.addComponent(newCC);  // Manual $create
        
        // If a custom function has been provided, use it            
        if (customFn) {
            customFn(newCC, referenceEl);
        }                                    
    }
        
    // Recursive call
    for(var i = 0; i < referenceEl.childNodes.length; i++) {
        cloneElementCCs(referenceEl.childNodes[i], newID, customFn);
    }
    
}

function disposeElementCCs(element) {
    if (element.id && $find(element.id)) {
        var elId = element.id;
        $find(element.id).dispose();
    }

    // Recursive call
    for(var i = 0; i < element.childNodes.length; i++) {
        disposeElementCCs(element.childNodes[i]);
    }
}

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();