/**
 * Copyright (c) 2006 IBM. All Rights Reserved.
 */
if (typeof wpf_ppr == "undefined")
{

// Object used to do partial page refresh.
var wpf_ppr = {
    // Submit the form, then update the indicated areas based on what returns.
    submit: function(form, idlist, hdlr, handlerOpts) {
       var myself = this;
       myself.startLoad();
       var options = {
            url: form.action,
            load: function(type, data, evt) { 
                myself.endLoad();
                (hdlr || wpf_ppr.explicitHandler).update(data, idlist, handlerOpts);  
            },
            error: function(type, error) { myself.endLoad(); myself.error(type, error); }
       };
       if (form.elements)
           options["formNode"] = form;
       this.bind(options);
    },
    
    // Invoke URL, then update the indicated areas based on what returns.
    load: function(url, idlist, hdlr, handlerOpts) { 
        var myself = this;
        myself.startLoad();
        this.bind({
            url: url,
            load: function(type, data, evt) { 
                myself.endLoad();            
                (hdlr || wpf_ppr.explicitHandler).update(data, idlist, handlerOpts); 
            },
            error: function(type, error) { myself.endLoad(); myself.error(type, error); }
        });
    },
    error: function(type, error) { debugError(error); },    
    // Can overload these to, e.g., show a progress indicator for long operations.
    startLoad: function() { },
    endLoad: function() {  },
    
    bind: function(opts) {
        if (typeof wpf_io == "undefined")
            dojo.io.bind(opts);
        else
            wpf_io.bind(opts);
    },
    
    debug: function(msg) {
        if (typeof dojo == "undefined")
            alert(msg);
        else
            dojo.debug(msg);
    },
    
    debugError: function(err) {
        if (typeof dojo == "undefined")
            alert(err);
        else
            dojo.debug(dojo.errorToString(err));
    },
    
    // Rebuild the Dojo widgets after the page is refreshed
    buildWidgets: function(idlist) {
	    if (typeof(dojo) != 'undefined' &&  dojo.parser && typeof(dojo.parser.parse) == 'function')
	    {      
		    for (var i = 0; idlist && i < idlist.length; i++)
		    {
		        var id = idlist[i];
		        var dst = document.getElementById(id);
		        if (dst)
		        {
		           wpf_ppr.removeControls(dst);
		           dojo.parser.parse(dst);
		        }     
		    }
	    }
    },
    
     // Remove the Dojo controls from the dijit.registry, otherwise the call to dojo.parser.parse(...) will fail since it adds them
     // This will walk from the specified element down
	 removeControls: function(element) { 
	 
	    // Only element nodes
	    if (element.nodeType == 1 )  
	    {  
	       var attrs = element.attributes;
	       if(attrs.getNamedItem("dojoType") != null)
	       {
	           var id = attrs.getNamedItem("id");

               if(id != null && id.value.length > 0 )
               { 
	              dijit.registry.remove(id.value);
	           }
	       }
	        var children = element.childNodes;                
	        for(var i=0; i < children.length; i++)
	        {    
	            wpf_ppr.removeControls(children[i]);
	        }
	    }
	},  
    
    
    
    // Handler which evaluates returned data as JavaScript. If idlist is also specified,
    // replace matching document elements with the returned HTML.
    scriptHandler: {
        update: function(data, idlist) { 
            if (data) {
                // See if this data has a direct-evaluation-prevention wrapper - if so, remove it.
                for (var i = 0; i < wpf_ppr.wrapperPatterns.length; i++) {
                    var regex = wpf_ppr.wrapperPatterns[i];
                    var result = data.match(regex);
                    if (result != null) {
                        data = result[1];
                        break;
                    }
                }               
                eval(data);
            }
        }
    },
    
    // Take HTML from data and use it to replace contents of elements whose IDs are in idlist.
    directHandler: {
        update: function(data, idlist) {
            for (var i = 0; idlist && i < idlist.length; i++)
            {
                var id = idlist[i];
                var dst = document.getElementById(id);
                if (dst)
                    dst.innerHTML = data;             
            }
            
            wpf_ppr.buildWidgets(idlist);
            // setTimeout(function() {wpf_ppr.buildWidgets(idlist)}, 1);            
        }
    },

    // This handler parses the data as HTML, and walks over it replacing areas in the
    // document DOM with matching IDs.
    explicitHandler: {
        // Given some HTML as text, replace the current DOM items
        // as specified in idlist.
        update: function(data, idlist, handlerOpts)
        { 
            // In IE, cache the temporary span; otherwise, re-create it each time.
            var isIE = /MSIE/.test(navigator.userAgent);  
            var tmp = null;
            if (isIE)
                tmp = document.getElementById("_wpf_ppr_temp_span");
            if (!tmp) {
                tmp = document.createElement("span");
                tmp.id = "_wpf_ppr_temp_span";
                tmp.style.display = "none";
                if (isIE)
                    document.body.appendChild(tmp);
            }
            tmp.innerHTML = data;
            var nchildren = tmp.childNodes.length;
            for (var n = 0; n < nchildren; n++)
            {
                var node = tmp.childNodes[n];
                wpf_ppr.explicitHandler.updateContent(node, idlist);
            }
            if (handlerOpts && handlerOpts.execScripts)
                wpf_ppr.executeScripts(tmp);            
            wpf_ppr.buildWidgets(idlist)
            // setTimeout(function() {wpf_ppr.buildWidgets(idlist)}, 1);            
        },

        // Recursive function that walks a tree of DOM Nodes,
        // fetches content from any whose id is contained in idlist
        // and replaces the corresponding element in the main document.
        updateContent: function(node, idlist)
        {
        
            var id = node.getAttribute ? node.getAttribute("id") : null;
            if (id)
            {
                var found = false;
                // If no idlist specified, then find replace contents of
                // all document DOM items whose IDs are the same as IDs in
                // incoming content.
                if (!idlist || idlist.length == 0)
                {
                    var dst = document.getElementById(id);
                    if (dst /* && dst.innerHTML != node.innerHTML */) // would checking be a win?
                    {                 
                        dst.innerHTML = node.innerHTML;                      
                        return;
                    }
                }
                else
                {
                    for (var i = 0; i < idlist.length; i++)
                    {
                        if (id == idlist[i])
                        {
                            var dst = document.getElementById(id);
                            if (dst) {                           
                                dst.innerHTML = node.innerHTML;                                
                            }
                            return;
                        }
                    }
                }
            }
            for (var c = node.firstChild; c != null; c = c.nextSibling)
            {
                wpf_ppr.explicitHandler.updateContent(c, idlist);
            }
        }
    }, // end of explicitHandler implementation
        
    debugHandler: {
        update: function(data, idlist) { debug(data); }
    },
    
    executeScripts: function(el) {
        var scptTxt = "";
        var scripts = el.getElementsByTagName("script");
        if (!scripts) return;
        for (var i = 0; i < scripts.length; i++)
        {
            var script = scripts[i];        
            var scpt = script.innerHTML;                 
            if (scpt) {
                scptTxt += scpt;
            }
            var src = script.src;
            if (src) {
                wpf_ppr.addScriptReference({src: src});
            }            
        }
        if (scptTxt)
            wpf_ppr.evaluateScriptText(scptTxt);        
    },
    
    evaluateScriptText: function(scptTxt) {
        // See if we have set up a function to evaluate scripts.
        if (typeof window._wpf_ppr_gloabal_eval  == "undefined")
        {
            // This call has the dual effects of testing for eval running in the global scope, 
            // and defining the function. If this defines the function globally, then it can be used.
            window.eval("var _wpf_ppr_gloabal_eval  = function(s) { window.eval(s); }");
        }
        if (typeof window._wpf_ppr_gloabal_eval  == "undefined")
        {
            // Here for IE, Safari, or in others where eval doesn't happen in global scope.
            window._wpf_ppr_gloabal_eval  = function(s)
            {   // Add script tag to head with specified contents, executing it.
                wpf_ppr.addScriptReference({text: s});
            };
        }
        window._wpf_ppr_gloabal_eval (scptTxt);
    },
    
    addScriptReference: function(opts) {
        var el = document.createElement("script");
        el.type = "text/javascript";
        el.defer = false;
        if (opts.text) el.text = opts.text;        
        if (opts.src) el.src = opts.src;
        var heads = document.getElementsByTagName("head");      
        if (heads.length) {
            heads.item(0).appendChild(el);
        } else {
             var head = document.createElement("head");
             head = document.documentElement.appendChild(head);
             head.appendChild(el);
        }     
    },
    
    // Script data may be wrapped to prevent direct execution - by default, we handle these three ways:
    wrapperPatterns: [
        /^\/\*(.*)\s*\*\/\s*$/m, // Simply commented-out
        /^\/\*-secure-\s*(.*)\s*\*\/\s*$/m, // Prototype-style commenting
        /^\s*while\s*\(\s*1\s*\)\s*;(.*)$/m // Google-style infinite loop prefix
    ]    

} // end wpf_ppr definition
} // end include guard

