﻿/// FRAMEWORK CLASS ///
//© 2008 SeatQuest LLC.
/// <reference path="ajax.js"/>


function FRAMEWORK()
{
    ///<summary>Initializes all the classes neccessary for this framework.</summary>
    this.path=this.get_path();
    this.detect_browser();
    
    //ELI 3.0.0 - I added the ability to turn a flag that will prevent the include.
    // instead the user will have to add a script element for each inclue in his html page.
    if (typeof(framework_disable_autoload) == 'undefined' || framework_disable_autoload == false) 
    {

        //ELI inclide the rest of javascript files that comprise the whole framework.
        this.include("ajax.js");
        this.include("debug.js");

        this.include("swfobject.js");
        this.include("zoomer.js");

        this.include("xsl.js");
        this.include("filter.js");
        
        this.include("xsl_loader.js");
        
        this.include("price_ranges.js");
        this.include("section_translation.js");
        this.include("section_logic.js");
        this.include("seat_logic.js");
        this.include("google_map.js");
    }
};

FRAMEWORK.version = "6.0.0"
FRAMEWORK.prototype.args = {
    filter:null,
    zoomer:null,
    debug:null
};

FRAMEWORK.prototype.debug = null;
FRAMEWORK.prototype.filter = null; // {base,version,full}
FRAMEWORK.prototype.zoomer = null; // {base,version,full}
FRAMEWORK.prototype.path = null; // {base,version,full}


FRAMEWORK.prototype.load=function(args)
{
    if(args){this.args=args;}

    var debug=this.args.debug ? this.args.debug :null;   
    //ELI debug comes first since it needs to be passed to all the other classes.
    if(!debug){debug={key_hook:true};}
    this.debug = new DEBUG(debug);
    
    this.load_with_debug();
       
};

FRAMEWORK.prototype.load_with_debug = function(){

    var google_map=this.args.google_map ? this.args.google_map :null;
    var show_google_map=this.args.show_google_map ? this.args.show_google_map :null;
 
    if(google_map){
        google_map.debug = this.debug;
        this.google_map=new GOOGLE_MAP(google_map);
    }   
    
    if(show_google_map == 1){
        this.google_map.load();
    }else{
        this.load_interactive_map_with_debug();
    }
    
    this.load_filter_with_debug();
}



FRAMEWORK.prototype.load_interactive_map_with_debug = function(){

    var zoomer=this.args.zoomer ? this.args.zoomer :null;
    var price_ranges=this.args.price_ranges ? this.args.price_ranges :null;
    var section_logic=this.args.section_logic ? this.args.section_logic :null;
    //var seat_logic=this.args.seat_logic ? this.args.seat_logic :null;
    var section_tanslation=this.args.section_tanslation ? this.args.section_tanslation :null;
    
    if(zoomer){
        zoomer.debug=this.debug;
        if(section_logic) {
            zoomer.enable_section_highlights = true;
        }else{
            zoomer.enable_section_highlights = false;
        }
        this.zoomer=new ZOOMER(zoomer);
    }
    
    if(section_tanslation){
        section_tanslation.debug = this.debug;
        section_tanslation.zoomer = this.zoomer;
        this.section_tanslation=new SECTION_TRANSLATION(section_tanslation);
    }
    
//    if(seat_logic){
//        seat_logic.debug = this.debug;
//        this.seat_logic=new SEAT_LOGIC(seat_logic);
//    }
    
    if(section_logic){
        section_logic.debug = this.debug;
        section_logic.zoomer = this.zoomer;
        section_logic.section_translation = this.section_tanslation;
        this.section_logic=new SECTION_LOGIC(section_logic);
        //resolve cross dependency
        this.zoomer.set_section_logic(this.section_logic);
    }
    
    if(price_ranges){
        price_ranges.debug=this.debug;
        this.price_ranges=new PRICE_RANGES(price_ranges);
    }
}

FRAMEWORK.prototype.load_filter_with_debug = function(){
    var filter=this.args.filter ? this.args.filter :null;
    //ELI load the filter class.
    if(filter)
    {
        filter.debug=this.debug;
        filter.zoomer=this.zoomer;
        if(this.price_ranges) {
            filter.price_ranges = this.price_ranges;
        } else {
             filter.price_ranges = null;
        }    
        filter.xsl_base_url=this.path.current.xsl + 'generate_api.xsl';
        //BOGDAN set the url for convertion xsl
        if(filter.convert_from_tb)
        {
            filter.xsl_for_conversion_url=this.path.current.xsl + filter.convert_from_tb +'.xsl';
        } 
        this.filter=new FILTER(filter); 
    }
}

FRAMEWORK.prototype.included = {};
FRAMEWORK.prototype.include = function (url) 
{
    //ELI this function is disabled until we solve the SAFARI issue.
    if(!this.included[url])
    {
        this.included[url]=url;
        
        //ELI url of script to download.
        var src=this.path.current.scripts + url;

        if(this.browser=='firefox' )
        {
            var head = document.getElementsByTagName('head')[0];
            var script=document.createElement('script');
            script.src=src;
            script.type='text/javascript';
            script.defer=false;
            //ELI this will help us debug the code in firebug.
            // document.write() does not allow any browser to debug the code.
            head.appendChild(script);
            return;
        }        

        //ELI write a script to the document.
        var ajax=this.get_url(src);
        var script=ajax.responseText;

//        if(this.browser=='chrome' )
//        {
//            eval.call(window,script);
//            return;
//        }
        
        //ELI protects our code from being debuged or looked at by any debugger of browser.
        this.write_script(script);
    }
};

FRAMEWORK.prototype.get_url=function(url)
{
    var ajax=null;
    if (window.XMLHttpRequest){ajax=new XMLHttpRequest();}else{ajax=new ActiveXObject('MSXML2.XMLHTTP.3.0');}
    if(ajax)
    {
        ajax.open("GET", url,false);
        ajax.send(null);
    }
    return ajax;
};


FRAMEWORK.prototype.write_script=function(script)
{
    if (!script){    return;}
    script='<script type="text/javascript">' + script+ '</script>';
    document.write(script);
};

//ELI get the framework path
FRAMEWORK.prototype.get_script = function (name)
{
    var head = document.getElementsByTagName('head')[0];
    if(!head){return null;}
    var scripts=head.getElementsByTagName('script');
    if(!scripts){return null;}
    for(i=0;i<scripts.length;i++)
    {
        var uri=parse_url(scripts[i].src);
        var f=uri.filename;
        var file=f.substring(0,f.indexOf('.'))
        f=file=='' ? f: file;
        if(f.toLowerCase()!=name){continue;};    
        return scripts[i];
    }
    return null;
};

//ELI get the framework path
FRAMEWORK.prototype.get_path = function ()
{
    var script = this.get_script("framework");
    if(!script){return null;}
    var uri=parse_url(script.src);
    var c= uri.source.split('/');
    var pos=-1;
    for(i=c.length;i>=0;i--)
    {   
        if(c[i]=='framework'){pos=i; break;}
    }
    if (pos==-1){return;}
    pos++;
    var base =c.slice(0,pos).join('/')+ '/';
    var version=c[pos] ;
    var path={
        base: base ,
        version: version,
        current: {
            base: base + version + '/',
            scripts: base + version + '/scripts/',
            xsl:  base + version + '/xsl/'}
    }
    return path;
};

FRAMEWORK.prototype.observe=function (element, event_name, handler) 
{
      var name = event_name;
      
      //ELI watch for an element on load.
      if((name=='onload' || name=='load') && typeof element=='string'){this.element_onload(element,handler);return;}

      if (element.addEventListener) {
        element.addEventListener(name, handler, false);
      } else {
        element.attachEvent("on" + name, handler);
      }
      return element;
};

FRAMEWORK.prototype.elements=[];
FRAMEWORK.prototype.elements_htimer=null;
FRAMEWORK.prototype.element_onload=function (id,callback) 
{
    this.elements.push({id:id,callback:callback});
    var _this=this;
    if(!this.elements_htimer)
    {
        this.elements_htimer=setInterval(function(){_this.element_search();},100);
    }
};

FRAMEWORK.prototype.element_search=function()
{
    for(i=this.elements.length-1;i>=0;i--)
    {
        var search=this.elements[i];
        var e = document.getElementById(search.id);
        if(e) {this.elements.splice(i,1);setTimeout(search.callback,1);}
    }
    if(this.elements.length<1) {clearInterval(this.elements_htimer);}
};

FRAMEWORK.prototype.browser=null;
FRAMEWORK.prototype.detect_browser=function()
{
    var version_search_string='';
	var search_string= function (data) 
	{
		for (var i=0;i<data.length;i++)	
		{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			version_search_string = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	};

	var search_version= function (dataString) 
	{
		var index = dataString.indexOf(version_search_string);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+version_search_string.length+1));
	};
	
	var browsers= [
	    {
		    string: navigator.userAgent,
		    subString: "Chrome",
		    identity: "Chrome"
	    },

	    { 	string: navigator.userAgent,
		    subString: "OmniWeb",
		    versionSearch: "OmniWeb/",
		    identity: "OmniWeb"
	    },
	    {
		    string: navigator.vendor,
		    subString: "Apple",
		    identity: "Safari"
	    },
	    {
		    prop: window.opera,
		    identity: "Opera"
	    },
	    {
		    string: navigator.vendor,
		    subString: "iCab",
		    identity: "iCab"
	    },
	    {
		    string: navigator.vendor,
		    subString: "KDE",
		    identity: "Konqueror"
	    },
	    {
		    string: navigator.userAgent,
		    subString: "Firefox",
		    identity: "Firefox"
	    },
	    {
		    string: navigator.vendor,
		    subString: "Camino",
		    identity: "Camino"
	    },
	    {		// for newer Netscapes (6+)
		    string: navigator.userAgent,
		    subString: "Netscape",
		    identity: "Netscape"
	    },
	    {
		    string: navigator.userAgent,
		    subString: "MSIE",
		    identity: "Explorer",
		    versionSearch: "MSIE"
	    },
	    {
		    string: navigator.userAgent,
		    subString: "Gecko",
		    identity: "Mozilla",
		    versionSearch: "rv"
	    },
	    { 		// for older Netscapes (4-)
		    string: navigator.userAgent,
		    subString: "Mozilla",
		    identity: "Netscape",
		    versionSearch: "Mozilla"
	    }
	];

    var oses = [
	    {
		    string: navigator.platform,
		    subString: "Win",
		    identity: "Windows"
	    },
	    {
		    string: navigator.platform,
		    subString: "Mac",
		    identity: "Mac"
	    },
	    {
		    string: navigator.platform,
		    subString: "Linux",
		    identity: "Linux"
	    }
    ];

    this.browser={
        id: search_string(browsers).toLowerCase() || null,
        version: search_version(navigator.userAgent) || search_version(navigator.appVersion) || null,
        os: search_string(oses) || null,
        toString:function(){return this.id;}
    }

};



//ELI assigns any matching properties from object on the right to the left.
FRAMEWORK.prototype.object_assign=function(a,b)
{
    for(var i in a)
    {   
        if(b[i])
        {
            a[i]=b[i];
        }
    }
}

//ELI copy any object properties from right to left.
FRAMEWORK.prototype.object_overwrite=function(a,b)
{
    for(var i in b)
    {   
        a[i]=b[i];
    }
}

//ELI compares the contents of common values in both objects, if one common value is different we fail the comparison.
FRAMEWORK.prototype.object_comparison=function(a,b)
{   
    if(a==null && b==null ){return true;}
    if(a==null || b==null ){return false;}
    for(var i in a)
    {   
        if(a[i]!=b[i])
        {
           return false;
        }
    }
    for(var i in b)
    {   
        if(b[i]!=a[i])
        {
           return false;
        }
    }
    
    return true;
}

//ELI this line is the most important line!!! do not remove.
var framework = new FRAMEWORK();

///////////////////////////////////////////////////////
//  GLOBAL FUNCTIONALITY
///////////////////////////////////////////////////////

//ELI generate an XML parser for gecko or XMLDOM for IE.
function XMLDOMObject()
{
    if (framework.browser.id != "explorer")
    {
        //ELI apply string parsed xsl
        return new DOMParser();
    } else  {
        xml = new ActiveXObject("Microsoft.XMLDOM");
        xml.async = false;
        return xml;
    }       
};

//ELI parse a URL.
function parse_url(sourceUri)
{
    var uriPartNames = ["source","protocol","authority","domain","port","path","directory_path","filename","query","anchor"];
    var uriParts = new RegExp("^(?:([^:/?#.]+):)?(?://)?(([^:/?#]*)(?::(\\d*))?)?((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[\\?#]|$)))*/?)?([^?#/]*))?(?:\\?([^#]*))?(?:#(.*))?").exec(sourceUri);
    var uri = {};
    
    for(var i = 0; i < 10; i++){
        uri[uriPartNames[i]] = (uriParts[i] ? uriParts[i] : "");
    }
    
    // Always end directoryPath with a trailing backslash if a path was present in the source URI
    // Note that a trailing backslash is NOT automatically inserted within or appended to the "path" key
    if(uri.directory_path.length > 0){
        uri.directory_path = uri.directory_path.replace(/\/?$/, "/");
    }
    
    return uri;
};

//ELI high-speed string manipulation.
function StringBuilder() {this.buffer = [];} 
StringBuilder.prototype.append = function append(s) {this.buffer.push(s); return this; }; 
StringBuilder.prototype.toString = function toString() {return this.buffer.join("");}; 

//ELI get a query parameter from the URL
function query(ji) 
{
    hu = window.location.search.substring(1);
    gy = hu.split("&");
    for (i=0;i<gy.length;i++) {
        ft = gy[i].split("=");
        if (ft[0] == ji) {
            return ft[1];
        }
    }
}

