﻿/// XSL_LOADER CLASS ///
function XSL_LOADER(args)
{
    var _this=this;
    this.args={};
    if(args){this.args=args;}

    if(!this.args.debug){this.debug=new DEBUG();}else{this.debug=this.args.debug;}

    this.xslt=new XSLT({debug:this.debug});

    //ELI create queue
    this.queue={};
    this.flags={};
        
    //ELI start looking for the ticket list DIV element.
    if(this.args.id)
    {
        this.flags.load=true;
        framework.observe(this.args.id,'onload',function(){_this.load();});
    }
   
    //ELI if we have XML and XSL urls we can start he download.
    if( this.args.xsl_url)
    {
        this.download();
        this.apply();
    }  
  
}

////ELI default parameters
//XSL_LOADER.prototype.args={
//    id:null,
//    xml_url:null,
//    xsl_url:null,
//    xml_ready:null,
//    string_params:null,
//    pre_render:null,
//    post_render:null,
//    debug:null
//}

XSL_LOADER.prototype.debug=null;
//XSL_LOADER.prototype.xslt=null;
XSL_LOADER.prototype.xml=null;
XSL_LOADER.prototype.xsl=null;

XSL_LOADER.prototype.flags={
    load:null,          //ELI FLAG which indicates that we are waiting for the ticket list DIV to load.
    download:null      //ELI FLAG which indicates that we started a download.
};

XSL_LOADER.queue={
    apply:null      //ELI apply() request was made but XSL & XML havent arrived yet.
};

XSL_LOADER.prototype.load=function()
{
    var _this=this;
    
    this.flags.load=null;
    if(this.queue.apply){this.queue.apply();}
};

//ELI in charge of firing the appropriate callbacks + mergin and rendering the XHTML to the document.
XSL_LOADER.prototype.inner_callback=function(ajax,url)
{

    var _this=this;
    if(url==this.args.xml_url && this.xml==null){this.xml=ajax; this.debug.time("Download XML",true); if(this.args.xml_ringdown){setTimeout(function(){_this.xml_ringdown(ajax,url);},1);}; }  
    if(url==this.args.xsl_url && this.xsl==null){this.xsl=ajax; this.debug.time("Download XSL",true); }

    //ELI return the parsed result with the ajax objects.
    if(this.xml && this.xsl )
    {
        //ELI make sure that we have valid xml, xsl before we proceed.
        if(this.xml.status!=200 || this.xsl.status!=200 ) { if(this.args.post_render){setTimeout(function(){_this.args.post_render(_this);},1);} return;}

        //ELI execute this.apply if it is in the queue.
        this.flags.download=null;
        var cb= function(){try{_this.queue.apply();}catch(ee){};} 
        if(this.queue.apply){setTimeout(cb,1);}
    }
};

XSL_LOADER.prototype.xml_ringdown= function (ajax,url)
{
    //ELI expecting an array
    if(this.args.xml_ringdown && this.args.xml_ringdown.length>0)
    {
        for(var i=0;i<this.args.xml_ringdown.length;i++)
        {
            var loader=this.args.xml_ringdown[i];
            loader.args.xml_url=url;
            loader.inner_callback(ajax,url);        
        }
     }
};

//ELI initiate the xml,xsl download.
XSL_LOADER.prototype.download= function ()
{
    //this.args=args;
    this.dom=null;
    this.xml=null;
    this.xsl=null;
    //this.queue.apply=null;
    this.flags.download=true;
    //this.flags.xml_ready=true;
    
    //ELI without this closure we would not be able to pass "this"
    // as a parameter in the this.args.callback
    this.debug.time("Download XML");
    this.debug.time("Download XSL");
    
    var _this=this;
    var cb=function(ajax,url){_this.inner_callback(ajax,url);}
    if(this.args.xml_url) new AJAX(this.args.xml_url,cb);
    if(this.args.xsl_url) new AJAX(this.args.xsl_url,cb);
};

XSL_LOADER.prototype.apply = function ()
{   
        
    //ELI set of checks before we can apply the filter:
    //1. did the XML & XSL download finish?
    //2. is the target DIV element ready yet? 
    var _this=this;

    //ELI remove this function from the queue.
    this.queue.apply=null;    

    //ELI if download is still going on then queue this call.
    //ELI if ticket list DIV is not ready then queue this call.
    if(this.flags.download || this.flags.load)
    {
        this.queue.apply=function(){_this.apply();};
        return;
    }

    //ELI no we are ready.
    this.ready_to_apply();
 
};

XSL_LOADER.prototype.ready_to_apply=function()
{
            
    ///<summary>filter and sort to the current client page.</summary>
    ///<parm name="args.params">parameters to override.</param>
    var _this=this;

    //ELI remove this function from the queue.
    this.queue.apply=null;    

    //ELI merge xml and xsl.
    var dom=this.xslt.merge(this.xml,this.xsl.responseText,this.args.string_params);
    
    //ELI render the HTML
    if(dom)
    {
        //ELI apply to div
        this.apply_to(this.args.id,dom);
    }
    
    //ELI fire when complete

    var xsl_stats = this.extract_xsl_stats(dom);
    if (this.args.complete) { this.debug.trap("XSL_LOADER->complete", function() { _this.args.complete(xsl_stats); }); }    

}


//ELI apply the dom tree to an element.
XSL_LOADER.prototype.apply_to = function(id,dom,encode)
{
    this.debug.time("HTML Render");

    var s=null;
    if(dom)
    {
        if(document.all)
        {
            s=this.toString(dom);
        }else{
            s=this.toString(dom);
            s=this.apply_firefox_fix(s);
        }
        if(encode){s=this.html_encode(s);}
    }      

    var e=null;
    if(typeof id=='string'){e=document.getElementById(id);}
    if(typeof id=='object'){e=id;}
    
    if(e)
    {
        if(typeof s=='string')
        {
            e.innerHTML=s;
        }
        if(typeof s=='object')
        {
            e.appendChild(s);
        }
        
    }
    this.debug.time("HTML Render",true);
    
};

XSL_LOADER.prototype.toString = function(dom,encode)
{
    //alert(dom.nodeValue);
    if(typeof dom=='string'){return dom;};
    if(typeof dom=='object')
    {
       if(framework.browser=='explorer'){return dom.xml;}
       return (new XMLSerializer()).serializeToString(dom);
    }
}

//ELI apply the dumb FF fix.
XSL_LOADER.prototype.apply_firefox_fix = function(s)
{
    if(framework.browser='firefox')
    {   
            //this.replaceHTML(e,this.html_decode(e.innerHTML));
            s=this.html_decode(s);
    }    
    return s;
};

//ELI decodes HTML entities.
XSL_LOADER.prototype.html_decode=function(value)
{
        return !value ? value : String(value).replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
};

//ELI encodes HTML entities.
XSL_LOADER.prototype.html_encode=function(value)
{
        return !value ? value : String(value).replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/""/g, '&quot;').replace(/[<]/g, "&lt;");
};

//ELI loads XML manually from text.
XSL_LOADER.prototype.load_xml=function(text)
{
/// <param name="text"/>
    
    var xml =null;
    if(framework.browser!='explorer' )
    {
       xml = XMLDOMObject().parseFromString(text, "text/xml");
     }else {
       //ELI create the XSL object.
       xml = XMLDOMObject();
       xml.loadXML(text);
     }
     
     this.debug.time("Download XML");
     var ajax = {responseXML:xml,status:200};
     this.args.xml_url="artificial_xml";
     this.inner_callback(ajax,this.args.xml_url);   
};

//ELI loads XML manually from URL.
XSL_LOADER.prototype.load_xml_url=function(_url)
{
    if(!_url){return;}
    this.dom=null;
    this.xml=null;
    this.args.xml_url = _url;

    this.debug.time("Download XML");
    this.flags.download=true;
    var _this=this;
    var cb=function(ajax,url){_this.inner_callback(ajax,url);}
    if(this.args.xml_url) new AJAX(this.args.xml_url,cb);

};

XSL_LOADER.prototype.extract_xsl_stats=function(dom)
{

    if(!dom) {return null;}

    var xmldom = null;
    if(dom.firstChild.nodeName.toLowerCase()=='xml')
    {
        xmldom=dom;
    }else{
        xmldom=dom.firstChild;
    };

    var stats = xmldom.getElementsByTagName('stats');
    
    if(!stats || stats.length<1){return null;}else{stats=stats[0];}

    var text=null;
    if(stats.text){text=stats.text;};
    if(stats.textContent){text=stats.textContent;};
//    if(stats.innerHTML){text=stats.innerHTML;};
    try{window.eval('var filter_stats_obj =' + text + ';');}catch(e){}
    stats.parentNode.removeChild(stats);     
    return typeof(filter_stats_obj)=='undefined' ? null : filter_stats_obj ;
};

