﻿/// FRAMEWORK CLASS ///
//© 2008 SeatQuest LLC.
/// <reference path="ajax.js"/>
FRAMEWORK.prototype.version = {FRAMEWORK:"6.6.0",ZOOMER:"3.4.0"};

//ELI constructor- called only when the keyword new is used in the code.
function FRAMEWORK()
{
    ///<summary>Initializes all the classes neccessary for this framework.</summary>

    //ELI detect which browser we are using.
    this.detect_browser();
    
    //ELI get the framework absolute path.
    this.path=this.get_path();
    
    //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 (!window.framework_disable_autoload && !window.unified) 
    {
        //ELI inclide the rest of javascript files that comprise the whole framework.
        this.load_script("json.js");
        
        this.load_script("bubble.js");
        this.load_script("ajax.js");
        this.load_script("debug.js");
        
        this.load_script("swfobject.js");
        this.load_script("zoomer.js");

        this.load_script("xsl.js");
        this.load_script("filter.js");
        this.load_script("scroller.js");
        
        this.load_script("xsl_loader.js");
                
        this.load_script("price_ranges.js");

        this.load_script("section_translation.js");
        this.load_script("section_logic.js");

        this.load_script("range_logic.js");
        this.load_script("seat_logic.js");
        
        this.load_script("google_map.js");
        
        this.load_script("section_map.js");
        
        this.load_script("facebook.js");
        this.load_script("promotion.js");
        this.load_script("curtain.js");
    }

    this.GECKO_XPATH_SUPPORT();
    this.ADD_MOUSE_SUPPORT();
    
    //ELI must be the last function in the constructor.
    this.register_callbacks();
};

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.bubble = null; // {base,version,full}
FRAMEWORK.prototype.path = null; // {base,version,full}

FRAMEWORK.prototype.tb =  
{
    enumerate:
    {
        1:'ticketsnow',
        2:'ticketnetwork',
        3:'ticketsolutions',
        4:'ebay',
        5:'razorgator',
        6:'stubhub',
        7:'seatquest',
        8:'livenation',
        9:'vividseats',
        10:'broadway',         
        255:'ticketmaster'
    },
    names:
    {
        1:'TicketsNow',
        2:'TicketNetwork',
        3:'TicketSolutions',
        4:'eBay',
        5:'RazorGator',
        6:'StubHub',
        7:'SeatQuest',
        8:'LiveNation',
        9:'VividSeats',
        10:'Broadway.com',        
        255:'Ticketmaster'
    },
    'ticketsnow':       1,
    'ticketnetwork':    2,
    'ticketsolutions':  3,
    'ebay':             4,
    'razorgator':       5,
    'stubhub':          6,
    'seatquest':        7,
    'livenation':       8,
    'vividseats':       9,
    'broadway':        10,    
    'ticketmaster':   255
};

FRAMEWORK.prototype.NATB = {22: true, 265: true, 12: true, 164: true, 150: true, 204: true, 120: true, 35: true, 64: true, 39: true, 99: true,
142: true, 136: true, 197: true, 56: true, 72: true, 182: true, 159: true, 69: true, 60: true, 168: true, 255: true, 74: true, 183: true, 312: true,
139: true, 208: true, 24: true, 143: true, 327: true, 133: true, 28: true, 28: true, 190: true, 16: true, 32: true, 232: true, 141: true, 163: true,
273: true, 199: true, 9: true, 42: true, 144: true, 86: true, 157: true, 134: true, 231: true, 248: true, 129: true, 224: true, 203: true, 54: true,
44: true, 145: true, 4: true, 30: true, 108: true, 80: true, 170: true, 34: true, 19: true, 95: true, 207: true, 121: true, 63: true, 18: true, 6: true,
317: true, 226: true, 227: true, 158: true, 152: true, 167: true, 61: true, 87: true, 14: true, 262: true, 115: true, 237: true, 128: true, 25: true,
154: true, 186: true, 196: true, 68: true, 78: true, 88: true, 172: true, 122: true, 92: true, 138: true, 181: true, 156: true, 130: true, 26: true,
30: true, 235: true, 279: true, 259: true, 124: true, 250: true, 7: true, 58: true, 188: true, 46: true};

//ELI register callbacks.
FRAMEWORK.prototype.register_callbacks=function(args)
{
    this.register_callback("zoomer_bridge_ready",this.version_check,false,true,'FRAMEWORK');
    this.register_callback("filter_xml_ready",this.filter_xml_ready,false,true,'FRAMEWORK');
}

//ELI compare zoomer version.
FRAMEWORK.prototype.version_check=function(args)
{
   //ELi check version compatibility
   if(!args || framework.version.ZOOMER != args.version)
   {
      framework.debug.console.error("ZOOMER VERSION MISMATCH!<BR>ZOOMER--------: v" + args.version);
      return;
   }
}

FRAMEWORK.prototype.load=function(args)
{
    //ELI store args.
    if(args)
    {
        framework.object_default(args,this.args);
        this.args = args;
    }
    
    //ELI LOAD DEBUG BEFORE ANYTHING ELSE!!!
    if(!this.args.debug){this.args.debug={key_hook:true};}
    this.debug = new DEBUG(this.args.debug);
    this.debug.console('EXPECTED VERSIONS:<BR>FRAMEWORK: v'+ this.version.FRAMEWORK + '<BR>ZOOMER--------: v' +  this.version.ZOOMER);    
    
    //ELI ZOOMER
    if(this.args.zoomer)
    {
        this.args.zoomer.debug=this.debug;
        this.zoomer=new ZOOMER(this.args.zoomer);
    }
    
    //ELI PRICE_RANGES
    if(this.args.price_ranges){
        this.args.price_ranges.debug=this.debug;
        this.price_ranges=new PRICE_RANGES(this.args.price_ranges);
    }
    
    //ELI BUBBLE
    if(!!this.args.bubble && !!this.args.bubble.enable)
    {
        this.bubble = new BUBBLE(this.args.bubble);
    }

    //ELI FILTER
    if(this.args.filter)
    {
        this.args.filter.debug=this.debug;
        this.args.filter.zoomer=this.zoomer;
        this.args.filter.price_ranges = this.price_ranges;
        this.args.filter.xsl_base_url=this.path.current.xsl + 'generate_api.xsl';
        //BOGDAN set the url for convertion xsl
        if(this.args.filter.convert_from_tb)
        {
            this.args.filter.xsl_for_conversion_url=this.path.current.xsl + this.args.filter.convert_from_tb +'.xsl';
        } 
        this.filter=new FILTER(this.args.filter); 
    }    

    //ELI SECTION_LOGIC or SEAT_LOGIC
    if(this.args.section_mode)
    {
        this.section_translation=new SECTION_TRANSLATION(this.args.section_translation);
        this.section_logic=new SECTION_LOGIC(this.args.section_logic);
    }else{
        this.seat_logic = new SEAT_LOGIC(this.args.seat_logic);
    }
    
    //ELI load the scroller.
    this.scroller = new SCROLLER({id:args.filter.id});

    //ELI load the scroller.
    this.section_map = new SECTION_MAP();

    //ELI add facebook capabilities...    
    this.facebook = new FACEBOOK();

    //ELI add promotion capabilities...    
    this.promotion = new PROMOTION();
    
    //ELI add promotion capabilities...    
    this.curtain = new CURTAIN();
    
//    //ELI add facebook capabilities...    
//    if(this.args.facebook)
//    {
//        this.facebook = new FACEBOOK();
//    }

//    //ELI add promotion capabilities...    
//    if(this.args.promotion)
//    {
//        this.promotion = new PROMOTION();
//    }
        
    //ELI run other classes on load async.
    framework.execute_callbacks("framework_load",args,true);
    
//ELI deprecated code of google maps  
//    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{
//    }
       
};

//ELI LOAD globals variable.
FRAMEWORK.prototype.load_globals=function(globals)
{

    //ELI preliminary check.
    if(!globals)
    {
        framework.debug = new DEBUG({key_hook:true});
        return;
    }
    
    //ELI load certain deafult parameters to globals in case they are missing.
    if(!globals.urls.list.xsl){globals.urls.list.xsl=framework.path.current.xsl + "customer_api_fixed.xsl";}
    if(!globals.urls.sections.xsl){globals.urls.sections.xsl=framework.path.current.xsl + "customer_api_sections.xsl";}
    
    //ELI start the framework.
    var show_all = false;
    if(query("show_all")=="true"){show_all=true;}
    
    var args={
		
        filter:{
            id:'div_ticket_list',                   //ELI id of the DIV that will contain the ticket list.
            //id: 'lst1',                   //ELI id of the DIV that will contain the ticket list.
            xml_url: globals.urls.list.xml,         //ELI link to the ticket XML
            xsl_url: globals.urls.list.xsl,         //ELI link to the table template XSL.
            show_all:show_all,                      //ELI show all tickets and ignore the sq_coords and sq_ga flags in XML.
			parking_tab:true,						//BOGDAN parking passes are not shown in tickets list if true. Overrides show_all for sq_ga flag
			no_filtering_for_parking:true,
			string_params:
			{
                'row_back_color': globals.customer.row_back_color, 
                'alt_back_color': globals.customer.alt_back_color,
                'zoom_in_path': globals.urls.zoomer.zoom_in_path,
                'js_cid': globals.query.cid,
                'js_pid': globals.query.pid,
                'js_subid': globals.query.subid,
                'js_bid': globals.query.bid,
                'js_iframe_mode': globals.customer.iframe_mode,
                'js_image_path': ''
            }
        },
        	
        zoomer:
        {
            id:'flashcontent',                  //ELI id of the DIV that will contain the zoomer object.
            help:0,                             //ELI add/remove the help message when the zoomer loads.
            zoom_ratio:1.5,                     //ELI control the zoom ratio of the zoom_in(), zoom_out() operations.
            //swf_url: globals.urls.zoomer.base + globals.urls.zoomer.filename,             //ELI URL to the swf object of the zoomer.
            map_xml: globals.urls.zoomer.base + globals.urls.zoomer.xml,  //ELI URL to the zoomer configuration XML.
            theme: globals.urls.zoomer.theme,          //ELI specify color for dialogs in the zoomer
            stmap: globals.urls.zoomer.static_map,     //ELI URL to static map to show in the zoomer instead of SeatQuest's venue map.
            activate_xtrace: framework.query('xtrace')     //ELI activate xtrace through query 
        },
        
//        google_map:{
//            id:'flashcontent',
//            venue_location: globals.google_maps.venue_location,
//            venue_coords: globals.google_maps.venue_coords    
//        },

        bubble: globals.bubble,
        section_mode: globals.sections.enable
//        show_google_map: globals.google_maps.enable

    }

    if(globals.sections.enable)
    {
        args.filter.xsl_url=globals.urls.sections.xsl;
        args.section_translation={'url':globals.sections.section_translation_url};
        args.section_logic=
        {
            selected_color:globals.customer.zoomer_selected,
            disabled_color:globals.customer.zoomer_disabled,
            list_row_colors:
            {
                normal:globals.customer.row_back_color,
                alternate:globals.customer.alt_back_color,
                hover:globals.customer.highlight_color
            }
        };
    }else{
        args.seat_logic=
        {
            list_row_colors:
            {
                normal:globals.customer.row_back_color,
                alternate:globals.customer.alt_back_color,
                hover:globals.customer.highlight_color
            }
        };
    }

    //ELI will be deprecated in the future.
    if(window.get_values) {args.filter.get_values=get_values;}              //ELI callback to your get_values function.
    if(window.set_values) {args.filter.set_values=set_values;}                  //ELI callback to your set_values function.
    if(window.pre_filter) {args.filter.pre_filter=pre_filter;}                  //ELI callback to your pre_filter function.
    if(window.post_filter) {args.filter.post_filter=post_filter;}                //ELI callback to your post_filter function.
    if(window.seat_selected) {args.zoomer.seat_selected=seat_selected;}
    
    framework.load(args);
};

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.load_script = function(url)
{
    //ELI this function is disabled until we solve the SAFARI issue.
    if(this.included[url]){return;}
    this.included[url]=url;
    
    var src=this.path.current.scripts + url;

    var script = '<script type="text/javascript" src="'+src+'"></script>';
    document.write(script);
    return;
   
}

FRAMEWORK.prototype.load_css = function(url)
{
    //ELI this function is disabled until we solve the SAFARI issue.
    if(this.included[url]){return;}
    this.included[url]=url;
      
    //ELI url of script to download.
    var src=this.path.current.css + url;
    var fileref=document.createElement("link")
    fileref.setAttribute("rel", "stylesheet")
    fileref.setAttribute("type", "text/css")
    fileref.setAttribute("href", src)
    if (typeof fileref!="undefined")
    document.getElementsByTagName("head")[0].appendChild(fileref)
}

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 a scripts path
FRAMEWORK.prototype.get_script = function (name)
{
    var scripts=document.getElementsByTagName('script');
    if(!scripts){return null;}
    for(var 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(var 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={
        webroot: c.slice(0,pos-1).join('/')+ '/',
        base: base ,
        
        //version: version,
        current: 
        {
            base: base,
            scripts: base + 'scripts/',
            css: base + 'css/',
            xsl:  base + 'xsl/',
            swf:  base + 'swf/'
        }
    }
    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.attach_event=function (element, event_name, handler) 
{
    if(!element){return;}
    if (element.addEventListener) 
    {
        element.addEventListener(event_name, handler, false);
    } else {
        element.attachEvent("on" + event_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(var i=this.elements.length-1;i>=0;i--)
    {
        var search=this.elements[i];
        var e=null;
        
        //ELI implement dom load
        if(search.id=='dom')
        {
            e = document.getElementsByTagName("BODY");
            if(!!e){e = e[0];}
            if(!!e.onload) {e.onload= search.callback;}
            if(!!window.addEventListener) {window.addEventListener('load',  search.callback,false);}
            this.elements.splice(i,1);
            return;
        }else{
            e = document.getElementById(search.id);
        }
        
        if(!!e) {
            //framework.debug.console("found: " + search.id + " , " + e.isContentEditable);
            //if(!!e.attachEvent) e.attachEvent('onload', search.callback);
            //if(!!e.addEventListener) e.addEventListener('load', search.callback,false);
            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 copy any object properties from right to left.
FRAMEWORK.prototype.object_default=function(a,b)
{
    //ELI b is the default values.
    for(var i in b)
    {
       if(!a[i])
       {    
        a[i]=b[i];
       }
    }
}

//ELI copy any object properties from right to left.
FRAMEWORK.prototype.apply_defaults=function(args,defaults)
{
    var a = args;
    var d = defaults;

    if(!d){return a;}
    if(!a){return d;}
    
    //ELI b is the default values.
    var result ={};
    for(var i in d)
    {
        if(d.hasOwnProperty(i))
        {
            result[i] = a[i] ? a[i] : d[i];
        }
    }
    return result;
}

//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;
}


FRAMEWORK.prototype.get_size = function(obj) 
{
    if(!obj){return [0,0];}
    return [obj.clientWidth,obj.clientHeight];
}


FRAMEWORK.prototype.find_offset = function(obj) 
{
    if(!obj){return [0,0];}
	var curleft = curtop = 0;
	if (obj.offsetParent) 
	{
	    do 
	    {
		    curleft += obj.offsetLeft;
		    curtop += obj.offsetTop;
	    } while (obj = obj.offsetParent);
	}
	return [curleft,curtop];
}

FRAMEWORK.prototype.viewable_size = function() {
  var myWidth = 0, myHeight = 0;
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    myWidth = window.innerWidth;
    myHeight = window.innerHeight;
  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
  var result={};
  result.width=myWidth;
  result.height=myHeight;
  return result;
}

FRAMEWORK.prototype.inside_element = function(e,point) 
{
    if(!e ||!point){return;}

    //ELI if we are outside the zoomer area we should kill the bubbble.
    var offset = framework.find_offset(e);

    if(!point.x){point.x=point[0];point.y=point[1];}    
    
    //ELI are we outside top left?
    if(point.x<offset[0] || point.y<offset[1])
    {
        return false;
    }

    //ELI are we outside bottom right? 
    var size = framework.get_size(e);   
    if(point.x>offset[0] + size[0] || point.y>offset[1]+size[1])
    {
        return false;
    }
    
    return true;
}

FRAMEWORK.prototype.GECKO_XPATH_SUPPORT=function()
{
    //if( typeof XMLDocument == "undefined" ){ XMLDocument = Document; }

    // check for XPath implementation 
    if( document.implementation.hasFeature("XPath", "3.0") ) 
    { 
       // prototying the XMLDocument 
       XMLDocument.prototype.selectNodes = function(cXPathString, xNode) 
       { 
          if( !xNode ) { xNode = this; } 
          var oNSResolver = this.createNSResolver(this.documentElement) 
          var aItems = this.evaluate(cXPathString, xNode, oNSResolver, 
                       XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null) 
          var aResult = [];
          for( var i = 0; i < aItems.snapshotLength; i++) 
          { 
             aResult[i] =  aItems.snapshotItem(i);
          } 
          return aResult;
       } 
       // prototying the Element 
       Element.prototype.selectNodes = function(cXPathString) 
       { 
          if(this.ownerDocument.selectNodes) 
          { 
	         return this.ownerDocument.selectNodes(cXPathString, this);
          } 
          //else{throw "For XML Elements Only";} 
       } 
    } 


    // check for XPath implementation 
    if( document.implementation.hasFeature("XPath", "3.0") ) 
    { 
       // prototying the XMLDocument 
       XMLDocument.prototype.selectSingleNode = function(cXPathString, xNode) 
       { 
          if( !xNode ) { xNode = this; } 
          var xItems = this.selectNodes(cXPathString, xNode);
          if( xItems.length > 0 ) 
          { 
             return xItems[0];
          } 
          else 
          { 
             return null;
          } 
       } 
       
       // prototying the Element 
       Element.prototype.selectSingleNode = function(cXPathString) 
       {	
          if(this.ownerDocument.selectSingleNode) 
          { 
             return this.ownerDocument.selectSingleNode(cXPathString, this);
          } 
          //else{throw "For XML Elements Only";} 
       } 
    }		

}

FRAMEWORK.prototype.string_to_xml=function(text)
{
    if(!text){return;}
    var xml =null;
    if(framework.browser!='explorer' )
    {
       xml = new DOMParser().parseFromString(text, "text/xml");
     }else {
       //ELI create the XSL object.
       xml = XMLDOMObject();
       xml.loadXML(text);
     }
     return xml;
}

//ELI decodes HTML entities.
FRAMEWORK.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.
FRAMEWORK.prototype.html_encode=function(value)
{
        return !value ? value : String(value).replace(/&/g, "&amp;").replace(/>/g, "&gt;").replace(/""/g, '&quot;').replace(/[<]/g, "&lt;");
};

//ELI get a query parameter from the URL
FRAMEWORK.prototype.query=function(name) 
{
    hu = window.location.search.substring(1);
    gy = hu.split("&");
    for (i=0;i<gy.length;i++) {
        ft = gy[i].split("=");
        if (ft[0] == name) {
            return ft[1];
        }
    }
    return null;
}

//ELI get a query parameter from the URL
FRAMEWORK.prototype.remove_query=function(url,parameter) 
{
    var urlparts= url.split('?');

    if (urlparts.length>=2)
    {
      var urlBase=urlparts.shift(); //get first part, and remove from array
      var queryString=urlparts.join("?"); //join it back up

      var prefix = encodeURIComponent(parameter)+'=';
      var pars = queryString.split(/[&;]/g);
      for (var i= pars.length; i-->0;)               //reverse iteration as may be destructive
          if (pars[i].lastIndexOf(prefix, 0)!==-1)   //idiom for string.startsWith
              pars.splice(i, 1);
      url = urlBase+'?'+pars.join('&');
    }
    return url;
}

//ELI REGISTER A CALLBACK:
// you can register many callbacks in one section ([] denotes optional parameter):
//1. section -> the location in the framework where this function will be called.
//   example: filter_xml_ready is called at FILTER class in method XML_READY.
//2. fn -> is your function reference, the function you would like our callback mechanism to call when it hits that section.
//   when you callback is called we pass a object called "args" to it which will contain all the values that the callee wanted to to be aware about.
//3. [dont_pop] -> by default your function will be called once and then pop out of the callback queue, set this value to true to make it stay.
//4. [synchronous] -> by default your function is executed Asynchroniously from the queue, set this value to true to make it call synch.
//5. [provider] -> by default we mark all functions as FRAMEWORK functions. you must override it to 
//5. [deregister] -> by default is false! will deregister all FRAMEWORK callbacks on that section.
//ELI get a query parameter from the URL
FRAMEWORK.prototype.registered_callbacks={};
FRAMEWORK.prototype.register_callback=function(section,fn,dont_pop,synchronous,provider,deregister) 
{
    var _this = framework;
    if(!_this){_this=this;}

    if(!provider){provider="FRAMEWORK";}
    if(deregister){_this.deregister_callbacks(section);}

    var callbacks = _this.registered_callbacks[section];
    if(!callbacks){callbacks=[];}
    var callback ={'fn':fn,'synchronous':synchronous,'dont_pop':dont_pop,'provider':provider};
    callbacks.push(callback);
    _this.registered_callbacks[section]=callbacks;
}

//ELI remove all registered callbacks from a section ([] denotes optional parameter).
// you can deregister many callbacks in one section according to their provider:
//1. section -> the location in the framework where this function will be called.
//   example: filter_xml_ready is called at FILTER class in method XML_READY.
//2. [provider] -> if you ommit the provider parameter then we take out all the framework callbacks in this section.
FRAMEWORK.prototype.deregister_callbacks=function(section,provider) 
{
    var _this = framework;
    if(!section){return;}    
    if(!provider){provider="FRAMEWORK";}    
    var callbacks = _this.registered_callbacks[section];
    if(!callbacks){return;}
    var deregistered_callbacks=[];
    for(var i=callbacks.length-1;i>=0;i--)
    {
        var callback = callbacks[i];
        
        //ELI Execute the function sync or async.
        if(!!callback && callback.provider==provider)
        {
            deregistered_callbacks.push(callbacks.pop());
        }
    }
    return deregistered_callbacks;   
}

//ELI remove one callback at the time starts from the end registered callbacks from a section ([] denotes optional parameter).
// you can deregister many callbacks in one section according to their provider:
//1. section -> the location in the framework where this function will be called.
//   example: filter_xml_ready is called at FILTER class in method XML_READY.
//2. [provider] -> if you ommit the provider parameter then we take out all the framework callbacks in this section.
FRAMEWORK.prototype.deregister_callback=function(section,provider) 
{
    var _this = framework;
    if(!section){return;}    
    if(!provider){provider="FRAMEWORK";}    
    var callbacks = _this.registered_callbacks[section];
    if(!callbacks){return;}
    for(var i=callbacks.length-1;i>=0;i--)
    {
        var callback = callbacks[i];
        
        //ELI Execute the function sync or async.
        if(!!callback && callback.provider==provider)
        {
            callbacks.pop();
            return callback;
        }
    } 
}

//ELI execute the callbacks in the particular section.
//default execution is async.
FRAMEWORK.prototype.execute_callbacks=function(section,args,force_synchronous) 
{
    var _this = framework;
    var callbacks = _this.registered_callbacks[section];
    if(!callbacks)
    {
        if(_this.debug){_this.debug.console.error("FRAMEWORK -> no callbacks for: " + section);}
        _this.registered_callbacks[section] = []; //ELI this stops the framework from warnning us about the missing callback.
        return;
    }
    
    //ELI LIFO
    for(var i=callbacks.length-1;i>=0;i--)
    {
        var callback = callbacks[i];
        
        //ELI wrapper function for our callback.
        var fn = function()
        {
            try
            {
                callback.fn(args);
            }catch(e){
                if(_this.debug){_this.debug.error("CALLBACK -> " + callback.provider + ": " + section,e);}
            }
        }
        
        //ELI Execute the function sync or async.
        if(!callback.synchronous && !force_synchronous)
        {
            setTimeout(fn,0);
        }else{
            fn();
        }
        
//        //ELI pop/or not  it from the queue.
//        if(!callback.dont_pop){callbacks.pop();}
    }
    
    for(var i=callbacks.length-1;i>=0;i--)
    {
        var callback = callbacks[i];
        //ELI pop/or not  it from the queue.
        if(!callback.dont_pop){callbacks.pop();}
    }
}

//ELI fastest trim ever design on the face of earth!!!
//http://blog.stevenlevithan.com/archives/faster-trim-javascript
FRAMEWORK.prototype.trim = function(str) 
{
	str = str.replace(/^\s+/, '');
	for (var i = str.length - 1; i >= 0; i--) {
		if (/\S/.test(str.charAt(i))) {
			str = str.substring(0, i + 1);
			break;
		}
	}
	return str;
}

//ELI fastest trim ever design on the face of earth!!!
//http://blog.stevenlevithan.com/archives/faster-trim-javascript
FRAMEWORK.prototype.unique = function(ra) 
{
    var unique={length:0};
    var result=[];
    for(var i=0;i<ra.length;i++)
    {
        if(!unique[ra[i]])
        {
            result.push(ra[i]);
            unique[ra[i]]=true;
            unique.length++;
        }
    }
    return result;
}

FRAMEWORK.prototype.get_scroll_offset = function () 
{
  var scrOfX = 0, scrOfY = 0;
  if( typeof( window.pageYOffset ) == 'number' ) {
    //Netscape compliant
    scrOfY = window.pageYOffset;
    scrOfX = window.pageXOffset;
  } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
    //DOM compliant
    scrOfY = document.body.scrollTop;
    scrOfX = document.body.scrollLeft;
  } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
    //IE6 standards compliant mode
    scrOfY = document.documentElement.scrollTop;
    scrOfX = document.documentElement.scrollLeft;
  }
  return [ scrOfX, scrOfY ];
}

FRAMEWORK.prototype.mouse=null;
FRAMEWORK.prototype.event=null;
FRAMEWORK.prototype.ADD_MOUSE_SUPPORT = function()
{
  
    // Detect if the browser is IE or not.
    // If it is not IE, we assume that the browser is NS.
    var IE = document.all?true:false

    // If NS -- that is, !IE -- then set up for mouse capture
    if (!IE) document.captureEvents(Event.MOUSEMOVE)

    // Temporary variables to hold mouse x-y pos.s
    var tempX = 0
    var tempY = 0
    
    // Main function to retrieve mouse x-y pos.s
    var getMouseXY = function (e) 
    {
      if (IE) { // grab the x-y pos.s if browser is IE
        framework.event=event;
        if(!document.body){return;}
        var scroll_offset = framework.get_scroll_offset();
        tempX = event.clientX + scroll_offset[0];
        tempY = event.clientY + scroll_offset[1];
      } else {  // grab the x-y pos.s if browser is NS
        framework.event=e;
        tempX = e.pageX
        tempY = e.pageY
      }  
      // catch possible negative values in NS4
      if (tempX < 0){tempX = 0}
      if (tempY < 0){tempY = 0} 
       
      // show the position values in the form named Show
      // in the text fields named MouseX and MouseY
      // ELI add mouse xy support.
      if(!framework.mouse){framework.mouse={};}
      var xy = framework.mouse;
      xy[0]= tempX;
      xy[1]= tempY;
      xy['x']= tempX;
      xy['y']= tempY;
  
      var args = {xy:xy};
      if(framework)
      {
        framework.execute_callbacks("framework_mouse_move",args)
      }
      return true
    }

    // Set-up to use getMouseXY function onMouseMove
    document.onmousemove = getMouseXY;
}

//ELI
FRAMEWORK.prototype.remove_class_name = function(e,name)
{
    var element = framework.get_element(e);
    if(!element){return;}
    var names = element.className.split(' ');
    var result = "";   
    for(var i=names.length-1;i>-1;i--)
    {
        var n = names[i];
        if(n!="" && n.toLowerCase()!=name.toLowerCase())
        {
            result+=n + ' '; 
        }
    }
    element.className = result;
}

FRAMEWORK.prototype.add_class_name = function(e,name)
{
    var element = framework.get_element(e);
    if(!element){return;}
    element.className += ' ' + name;
}

FRAMEWORK.prototype.set_style = function(e,name,value)
{
    var element = framework.get_element(e);
    if(!element){return;}
    if(element.style[name]==undefined){return;}
    element.style[name] = value;
}

FRAMEWORK.prototype.get_element = function(e,child)
{
    if(!e){return;}
    var element = e;
    if(typeof e != 'object'){element = document.getElementById(e);}
    if(isNaN(child)){return element;}
    if(!element.hasChildNodes){return;}
    if(child>element.childNodes.length-1){return;}
    return element.childNodes(child);
}

FRAMEWORK.prototype.set_cookie = function (name, value)
{
    if (window.localStorage) {
        localStorage.setItem(name,value);
    } else {
        var ExpireDate = new Date ();
        ExpireDate.setTime(ExpireDate.getTime() + (expiration * 24 * 3600 * 1000));
        document.cookie = name + "=" + escape(value) + "";//((expiration == null) ? "" : "; expires=" + ExpireDate.toGMTString());
    }
}

FRAMEWORK.prototype.get_cookie = function (name) 
{
    if (window.localStorage) {
        return localStorage.getItem(name);
    } else {
        if (document.cookie.length > 0) 
        { 
            begin = document.cookie.indexOf(name+"="); 
            if (begin != -1)
            { 
                begin += name.length+1; 
                end = document.cookie.indexOf(";", begin);
                if (end == -1) end = document.cookie.length;
                return unescape(document.cookie.substring(begin, end)); 
            }   
        }
        return null;
    }
}

FRAMEWORK.prototype.del_cookie = function (name) 
{
    if (window.localStorage) {
        localStorage.removeItem(name);
    } else {
        if (this.get_cookie(name)) 
        {
            document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
        }
    }
}

FRAMEWORK.prototype.cookie={};
FRAMEWORK.prototype.cookie.set = function (name, value, exp)
{
    //ELI exp in days.
    if(exp)
    {
        var ExpireDate = new Date();
        ExpireDate.setTime(ExpireDate.getTime() + (exp * 24 * 3600 * 1000));
        document.cookie = name + "=" + escape(value) + "; expires=" + ExpireDate.toGMTString() + "; path=/; domain=." + document.location.hostname;
    }else{
        document.cookie = name + "=" + escape(value) + "";
    }
    
}

FRAMEWORK.prototype.cookie.get = function (name) 
{
    if (document.cookie.length > 0) 
    { 
        begin = document.cookie.indexOf(name+"="); 
        if (begin != -1)
        { 
            begin += name.length+1; 
            end = document.cookie.indexOf(";", begin);
            if (end == -1) end = document.cookie.length;
            return unescape(document.cookie.substring(begin, end)); 
        }   
    }
    return null;
}

FRAMEWORK.prototype.cookie.del = function (name) 
{
    if (framework.cookie.get(name)) 
    {
        document.cookie = name  +'=; expires=Thu, 01-Jan-70 00:00:01 GMT' + '; path=/; domain=.' + document.location.hostname;
    }
}

FRAMEWORK.prototype.isSeatQuest = function () 
{
    var cid = framework.query('cid');
    if(cid==null || cid=='3' || cid==''|| cid=='78336')
    {
        return true;
    }
    return false;
}

//ELI compare zoomer version.
FRAMEWORK.prototype.filter_xml_ready = function(args)
{
    var bid = framework.query('bid');
    if(!bid || bid==''){return;}
    
    var dom = framework.filter.xml.responseXML;
    if(!dom){return null;}
    
    framework.debug.time("Apply BID Filter");

    var rows=dom.getElementsByTagName('row');
    if(!rows){return null;}
   
    for(var i=rows.length-1;i>=0;i--)
    {
        var row=rows[i];
        var broker_id=row.getAttribute('BrokerID');
        if(broker_id && parseInt(broker_id)>0 && broker_id!=bid)
        {
            row.parentNode.removeChild(row);
        }
        
    }
    framework.debug.time("Apply BID Filter",true);
}

//ELI this line is the most important line!!! do not remove.
var framework = new FRAMEWORK();


///////////////////////////////////////////////////////
//  PROTOTYPES
///////////////////////////////////////////////////////

//Function.prototype.call = function(args,body)
//{
//    var args = Function.arguments;
//}

///////////////////////////////////////////////////////
//  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];
        }
    }
    return "";
}


