/* 
    * commons.js  Version 1.0
    * All common functions and global variables required to render pages.
	* 4/5/2010 Adding exclusion list functionality to pixel pro
	* 12/16/2009 Moved default pricing to common
	* 12/11/2009 Added generic pixel logic
	* 12/10/2009 Added more pixels
	* 10/2/2009  Added pixel processing
	* 10/28/2009 Moving Json toString function from partner_product since this would be commonly used
	* 
    * Copyright HRB Digital LLC
*/

//default pricing for online
var g_online_def_price= '{status:{tco:0,tcs:0,ver:1},partner:{cid:"otpPartnerID=0&pgm=13534200",partnerName:"-",partnerType:"normal",partnerWelcome:"na",otpPartnerID:"0",partnerTunnel:0,partnerID:"0",partnerActive:1},'+
'prodList:['+
//Extension
'{pid:"188",pn:"-",sn:"/loginRedirect.html?TaxType=TCL&FV=T&HT=F&OtpExt=1&TaxYear=2010",lm:"188.html",bpr:"19.95",ppr:"19.95",sk:"EXT",pl:"O",on:"extension"},'+
//Best of Both State -- 193
'{pid:"193",pn:"-",sn:"/loginRedirect.html?TaxType=SIG&FV=T&HT=F&TaxYear=2010",lm:"193.html",bpr:"39.95",ppr:"39.95",sk:"SIGSTA",pl:"O",on:"best_of_both_state"},'+
//Ask a tax advisor -- 44
'{pid:"44",pn:"-",sn:"/loginRedirect.html?TaxType=TCL&FV=T&HT=F&Target=ATA&TaxYear=2010",lm:"44.html",bpr:"19.95",ppr:"19.95",sk:"ATAEMAILBILL",pl:"O",on:"ata"},'+
//Office service -- 65
'{pid:"65",pn:"-",sn:"/universal/office_locator.html?&otpPartnerID=0&pgm=13534200&otpPartnerId=0",lm:"65.html",bpr:"0.00",ppr:"0.00",sk:"NA",pl:"R",on:"-"},'+
//Office service -- 64
'{pid:"64",pn:"-",sn:"-",lm:"64.html",bpr:"0.00",ppr:"0.00",sk:"NA",pl:"R",on:"-"},'+
//Online office state -- 191
'{pid:"191",pn:"-",sn:"/loginRedirect.html?TaxType=PTS&FV=T&HT=F&TaxYear=2010",lm:"191.html",bpr:"34.95",ppr:"34.95",sk:"PTSSTA",pl:"O",on:"ptssta_online_office_state"},'+
//FREE -- Fed 201
'{pid:"201",pn:"-",sn:"/loginRedirect.html?TaxType=TCF&FV=T&HT=F&TaxYear=2010",lm:"201.html",bpr:"0.00",ppr:"-1",sk:"TCFFED",pl:"O",on:"free_edition_fed"},'+
//FREE -- State
'{pid:"202",pn:"-",sn:"/loginRedirect.html?TaxType=TCF&FV=T&HT=F&TaxYear=2010",lm:"202.html",bpr:"30.95",ppr:"30.95",sk:"TCFSTA",pl:"O",on:"free_edition-state"},'+
//Online Office -- 62
'{pid:"62",pn:"-",sn:"/loginRedirect.html?TaxType=PTS&FV=T&HT=F&TaxYear=2010",lm:"62.html",bpr:"109.95",ppr:"109.95",sk:"PTSFED",pl:"O",on:"online_office_default"},'+
//TCO Split page -- 31
'{pid:"31",pn:"-",sn:"-",lm:"31.html",bpr:"0.00",ppr:"0.00",sk:"NA",pl:"O",on:"parent"},'+
//Basic State -- 194
'{pid:"194",pn:"-",sn:"/loginRedirect.html?TaxType=TCL&FV=T&HT=F&TaxYear=2010",lm:"194.html",bpr:"39.95",ppr:"39.95",sk:"TCLSTA",pl:"O",on:"basic_state"},'+
//Extension Filing split page -- 69
'{pid:"69",pn:"-",sn:"-",lm:"69.html",bpr:"0.00",ppr:"0.00",sk:"NA",pl:"O",on:"extension"},'+
//Best of Both -- 33
'{pid:"33",pn:"-",sn:"/loginRedirect.html?TaxType=SIG&FV=T&HT=F&TaxYear=2010",lm:"33.html",bpr:"79.95",ppr:"79.95",sk:"SIGFED",pl:"O",on:"best_of_both_fed"},'+
//Premium State -- 192
'{pid:"192",pn:"-",sn:"/loginRedirect.html?TaxType=OPP&FV=T&HT=F&TaxYear=2010",lm:"192.html",bpr:"39.95",ppr:"39.95",sk:"PAID1040STA",pl:"O",on:"premium_state"},'+
//Basic -- 30
'{pid:"30",pn:"-",sn:"/loginRedirect.html?TaxType=TCL&FV=T&HT=F&TaxYear=2010",lm:"30.html",bpr:"34.95",ppr:"34.95",sk:"TCLFED",pl:"O",on:"basic"},'+
//Premium -- 32
'{pid:"32",pn:"-",sn:"/loginRedirect.html?TaxType=OPP&FV=T&HT=F&TaxYear=2010",lm:"32.html",bpr:"74.95",ppr:"74.95",sk:"PAID1040FED",pl:"O",on:"premium"},'+
//Deluxe -- 204
'{pid:"204",pn:"-",sn:"/loginRedirect.html?TaxType=TCD&FV=T&HT=F&TaxYear=2010",lm:"204.html",bpr:"49.95",ppr:"49.95",sk:"TCDFED",pl:"O",on:"deluxe_fed"},'+
//Deluxe state -- 205
'{pid:"205",pn:"-",sn:"/loginRedirect.html?TaxType=TCD&FV=T&HT=F&TaxYear=2010",lm:"205.html",bpr:"39.95",ppr:"39.95",sk:"TCDSTA",pl:"O",on:"deluxe_state"},'+

//MapPoint Office Locator -- 203
'{pid:"203",pn:"-",sn:"-",lm:"203.html",bpr:"0.00",ppr:"0.00",sk:"NA",pl:"R",on:"-"}]}';
//default pricing for software
//default pricing for software
var g_soft_def_price ='[{'+
//premium + State + E-file --36 preorder --134571300
'pid:"36",pn:"-",sn:"-",lm:"36.html",bpr:"74.95",ppr:"74.95",sk:"220813300",pl:"S",on:"tcs_premium_state"},'+
//premium and business)
'{pid:"38",pn:"-",sn:"-",lm:"38.html",bpr:"89.95",ppr:"89.95",sk:"200998500",pl:"S",on:"tcs_home_and_business"},'+
//Deluxe  w/o State -- 206
'{pid:"206",pn:"-",sn:"-",lm:"206.html",bpr:"44.95",ppr:"44.95",sk:"200998200",pl:"S",on:"tcs_deluxe_fed"},'+
//Deluxe + State  -- 207
'{pid:"207",pn:"-",sn:"-",lm:"207.html",bpr:"54.95",ppr:"54.95",sk:"191342400",pl:"S",on:"tcs_deluxe_state"},'+
//Basic + E-file -- 199
'{pid:"199",pn:"-",sn:"-",lm:"199.html",bpr:"29.95",ppr:"29.95",sk:"200997800",pl:"S",on:"tcs_basic_fed"},'+
//State -- 39
'{pid:"39",pn:"-",sn:"-",lm:"39.html",bpr:"36.95",ppr:"36.95",sk:"200981900",pl:"S",on:"tcs_state"},'+
//main software prod -- 34
'{pid:"34",pn:"-",sn:"-",lm:"34.html",bpr:"-",ppr:"-",sk:"-",pl:"S",on:"tcs_main"}]';

g_sys = {
    checkFlash : function (){
        if (navigator.plugins != null && navigator.plugins.length > 0) {
        var desc = (navigator.plugins['Shockwave Flash']==undefined)?null:navigator.plugins['Shockwave Flash'].description;
            try {
                return parseInt(desc.match(/[\d.]+\d{1} /g)); 
            }catch (e){
                return null;
            }
        }
        else {
        for(var i=10; i>=5; i--){
            try{
                var flash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash." + i);
                return i;
            }
            catch(e){}
            }
        }
        return null;
    },
    checkCookie: function (){
        if (navigator.cookieEnabled)
        {/*cater for the bug in chrome*/
            document.cookie = "$TESTNAME=$TESTVALUE; path=/";
            if(document.cookie==""){
                return false;}
            else return true;
        }
        else {return false;}
    },
    checkBrowser: function (){
        /*Add support for five different browsers*/
		var _ua=navigator.userAgent;
        if (/Firefox[\/\s](\d+\.\d+)/.test(_ua)){ 
        return 'FF';}
        else if (/MSIE (\d+\.\d+);/.test(_ua)){
        return 'IE';
        }
        else if (/Opera[\/\s](\d+\.\d+)/.test(_ua)){
        return 'Opera';
        }
        else if (/Netscape/.test(_ua)){
        return 'NN';
        }
        else if (/Chrome[\/\s](\d+\.\d+)/.test(_ua)){
        return 'Chrome';
        }
        else if (/Safari[\/\s](\d+\.\d+)/.test(_ua)){
        return 'Safari';
        }
        else{
            return navigator.appName;
        }
    }
    ,
    checkBrowserVer: function (){
		var _ua=navigator.userAgent;
		if (/Firefox[\/\s](\d+\.\d+)/.test(_ua)){ 
			return new Number(RegExp.$1);
		}
		else if (/MSIE (\d+\.\d+);/.test(_ua)){ 
			return new Number(RegExp.$1)
		}
		else if (/Opera[\/\s](\d+\.\d+)/.test(_ua)){ 
			return new Number(RegExp.$1)
		}
		else if (/Netscape6/.test(_ua)){//ns 6
		ns='Netscape6'
		return _ua.substr( (_ua.indexOf(ns) + ns.length + 1 ) ,3);
		}
		else if (/Netscape/.test(_ua)){//for ns 7 and 8
		ns='Netscape'
		return _ua.substr( (_ua.indexOf(ns) + ns.length + 1 ) ,3);
		}
    },
    checkOS: function(){
    return navigator.platform ;
    },
    checkSilverLight: function(){
        if (navigator.plugins != null && navigator.plugins.length > 0) {
            var desc = (navigator.plugins['Silverlight Plug-In']==undefined)?null:navigator.plugins['Silverlight Plug-In'].description;
            if (desc!=null && desc.length >0){
                return true;
            }
            else{
                return false;
            }
        }
        else{
            try{
                new ActiveXObject("AgControl.AgControl");
                return true;
            }
            catch (e){
                return false;
            }
        }
    },
	checkEnv: function(){
		var prodenv =new Array('7cc2e7dfbb7d976ff792d3a6b081a5dbe3bcda88','0c342fe190c132e84015c61525345ddb133bf41b','c2518c92be164f6d062e7d127a408105d4fa0bcf','9e8c3f67567af231e189570e625054a2f2326d6d','ec43ba4f1bf417229b1dd5052756acea6c0618db')	;
		var qaenv =new Array('d8e056986ec757838e3069fedb74a8d01ce18251','4cffc0353c97b0b1dc4f3c7f64d518b2a560ef7f');
		var devenv =new Array('98b9938995d7d63dcd7a58b3e5535a75f1aac2df','9607e2e5c5d4a7875aad8389edb351cb7c261204','aba57c16e61a4a84f885522615c27b475059757e','1311a9559c6e56f772120b0374ac539f8eb390a4','48e59efbd74638185dece843f5474075579bdf9c');
		for (var i=0;i< prodenv.length;i++ ){
			if(HRBsha(document.location.hostname) == prodenv[i]){
				return "PROD";
			}
		}
		for (var i=0;i< qaenv.length;i++ ){
			if(HRBsha(document.location.hostname) == qaenv[i]){
				return "QA";
			}
		}
		for (var i=0;i< devenv.length;i++ ){
			if(HRBsha(document.location.hostname) == devenv[i]){
				return "DEV";
			}
		}
		return null;
	},
	getCurrentYear: function(){
		var curryr ="2010"
		if (this.checkEnv() == 'DEV'){
			var sysdate = new Date();
			if ((sysdate.getFullYear())!=curryr){
				//alert('Please update the current year!')
				return null;
			}
	
		}
		return curryr;
	},
	getLoginUrl : function() {

		/* implement like:
			javascript:GB_showCenter('Login',g_login.getLoginUrl()='?ViewType=1',162,433);
		*/

		var tco_url = "https://taxes.hrblock.com/hrblock/DirectLogin/DirectLogin.aspx"; // always default to prod

		/*
		if (g_sys.checkEnv()=="DEV" || g_sys.checkEnv()=="QA"){
			//tco_url = PUT DEV URL HERE
			//tco_url = PUT Q/A URL HERE
		}
		*/

		return tco_url;
	}

}
function queryString( key )
{
    var re = new RegExp( "[?&]" + key + "=([^&$]*)", "i" );
    var offset = location.search.search( re );
    if ( offset == -1 ) return null;
    return RegExp.$1;
}
function Logger(errorlevel){ 
    this.maxlevel = errorlevel;
    this.tracknow=false;
    this.msg=new Array('');
    this.debug = function(msg) {
        if (this.maxlevel=="debug" && this.tracknow){
            this.msg[this.msg.length]=(new Date()).getTime()+"::debug::"+msg;
        }
     }
     this.error = function(msg) {
         if (this.tracknow){
            this.msg[this.msg.length]=(new Date()).getTime()+"::error::"+msg;
         }
         try
         {
            recordExceptionInOmniture("ERR",9,msg+"^"+g_sys.checkBrowser()+"^"+g_sys.checkBrowserVer());
         }
         catch (e)
         {
            g_log.debug('Call Failed: recordExceptionInOmniture("err",9,'+msg+':'+g_sys.checkBrowser()+'-'+g_sys.checkBrowserVer()+')');
         }
     }
    this.display=function(displaytype)
    {
       	var rp= prompt('Enter password','password');		
		if (rp==null || rp=='' || HRBsha(rp) != '0a57870cbcd658932ebca20dcf5c1b9f3bc35ca1'){
			alert('Sorry, you cannot access this page.');
			 return;
		 }
		if (displaytype=="alert"){
			 var alertmsg="";
			 for (var i=0;i<this.msg.length ; i++){
				alertmsg+=this.msg[i]+"\n";
			}
            alert(alertmsg);
        }
        else if (displaytype=="win"){
			 var winmsg="";
			for (var i=0;i<this.msg.length ; i++){
				winmsg+=this.msg[i]+"<br><br>";
			}
			var dbg_win= window.open ("","debugwin","resizable=1,width=600,height=350,scrollbars=1");
			dbg_win.document.write("<body><div id='d3' style='font-family:Verdana;font-size:11px;'><p align=center><b>Debug</b></p>"+winmsg+"</body>"); 
				 
			}
        }
    }


function ajaxreq(url,postData,success,fail,headers)
    {
		this._reqObj=null;
        this._url=url;
        this._post=postData;
        this._success=success;
        this._headers=headers;
        this._fail=fail;
        this.sendReq = function()
        {
            this._getReqObject();
            var tmpObj=this;
            if (this._reqObj==null ){
                var iframereq=new IframeRequest(this._success,this._fail);
                iframereq.open("POST",this._url,true);
                iframereq.send(this._post);
            }
            else {
                    tmpObj._reqObj.onreadystatechange=function ()
                    {
                        if(tmpObj._reqObj.readyState==4 ){
                            // add responseXML when required
                            if (tmpObj._reqObj.status==200){
								g_log.debug('AJAX request :: Response OK :: status::'+tmpObj._reqObj.status);
								var resTxt=tmpObj._reqObj.responseText;
								if (typeof(resTxt)=='undefined' || resTxt ==null )
								{
									g_log.error('E02');
									return;
								}
								resTxt = (resTxt.replace(/[\n\t\v\r\f]/g, ""));
								resTxt = resTxt.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, "");
								resTxt = resTxt.replace(/\'/g,"\\'");

								try{
									eval(tmpObj._success+'(\''+resTxt+'\')');
								}
								catch (e){
									g_log.error('F00:' +e.message);
									if(resTxt!=null){
									g_log.error('F01:' +resTxt.length);
									}
									g_log.debug('response text' +resTxt);
								}
                            }
                            else{
								g_log.error('E01:'+tmpObj._reqObj.status)
								eval(tmpObj._fail+'('+tmpObj._reqObj.status+')');
                            }
                        }
                    }
                    try{
                    //check if opening connection has any issues
                    if (this._post==null || this._post=="")
                    {
                        this._reqObj.open('GET', this._url, true);
                    }
                    else{
                        this._reqObj.open('POST', this._url, true);
                    }

                    }catch(e){g_log.error('E00');
					          eval(this._fail+'(\'E00\')');
					}
                    if (this._headers!=null && this._headers!='' )
                    {
                        var hdrlist =this._headers.split(",");
                        for (var i=0;i< hdrlist.length; i++)
                        {
                            var hrd =hdrlist[0].split(":");
                            this._reqObj.setRequestHeader(hrd[0],hrd[1]);
                        }
                    }
                    if (this._post!=null && this._post!="" )
                    {
                        this._reqObj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
                        this._reqObj.setRequestHeader("Content-length", this._post.length);
                        this._reqObj.setRequestHeader("Connection", "close");
                    }
                    g_log.debug('AJAX request :: POST DATA::'+this._post);
                this._reqObj.send(this._post);  
            }
        }
        this._getReqObject=function(){
            try{
                this._reqObj=new XMLHttpRequest(); 
                g_log.debug('AJAX request :: XMLHTTPRequest ');
            }
            catch (e){
                try{
                    this._reqObj=new ActiveXObject("Msxml2.XMLHTTP");
                    g_log.debug('AJAX request :: Msxml2.XMLHTTP ');

                }
                catch (e){

                    try{
                      this._reqObj=new ActiveXObject("Microsoft.XMLHTTP");
                        g_log.debug('AJAX request :: Microsoft.XMLHTTP ');

                    }
                    catch (e){
                    g_log.error("E03");
                    return null;
                  }
                }
              }
            return this._reqObj;
            }
        this.sendReq();
    }
    
/* 
following is the Iframe solution if there is failure create an activeX object with IE 
This would work only if http header info is not required in the request object. 
*/
var IframeRequest = function(success,fail)
{
    this.method = "POST";
    this.url = null;
    this.async = true;
    this.iframe = null;
    this.responseText = null;
    this._success=success;
    this._fail=fail;
    this.header = new Object();
    this.id = "_xmlhttp_"+(new Date()).getTime() ;
    this.container = document.body;
}

IframeRequest.prototype.open = function(method, url, async)
{
    this.method = method;
    this.url = url;
    this.async = async;
    this.readyState = 0;
    var tmpDiv = document.createElement("div");
    tmpDiv.style.display='none';
    tmpDiv.setAttribute("id", "iframe-div");
    this.iframe = document.createElement("IFRAME");
    this.iframe.id = this.id;
    if(document.getElementById(this.id) == null){
        tmpDiv.appendChild(this.iframe);
        this.container.appendChild(tmpDiv);
    }
    //this.setRequestHeader("___xmlhttp", "iframe");
}

IframeRequest.prototype.send = function(data){
    var frmC = [];
    frmC[frmC.length] = '<html><body><form method="' + this.method + '" action="' + this.url + '">';
    if(data != null && data.length > 0){
         var namevalpairList=data.split("&"); 
        for (var i=0;i<namevalpairList.length ;i++ )
        {
            var namevalpair = namevalpairList[i].split("=");
            frmC[frmC.length] = '<input type="hidden" name="'+namevalpair[0]+'" value="'+namevalpair[1]+'">';
        }
    }
    frmC[frmC.length] = '<s'+'cript>document.forms[0].submit();</s'+'cript>';
    frmC[frmC.length] = '</form></body></html>';
    this.iframe._xmlhttp = this;
    this.iframe._xmlhttp._fix = -1;
    this.iframe._xmlhttp.responseText = null;
    this.iframe.onreadystatechange = this._onreadystatechange;
    this.iframe.src = "javascript:document.write('" + frmC.join('').replace(/\'/g,"\\'").replace(/\r\n/g, "\\r\\n") + "');void(0);";

}

IframeRequest.prototype._onreadystatechange = function(){
    this._xmlhttp._fix++;
    if(this._xmlhttp._fix < 1){
        return;
	}
    if(this._xmlhttp._fix == 1){
        this._xmlhttp.readyState = 1;
    }
    else if(this._xmlhttp._fix > 1){
        g_log.debug('AJAX request IFRAME::  '+this.readyState);
        switch(this.readyState.toString())
        {
            case "loading":
                this._xmlhttp.readyState = 2;
                break;
            case "interactive":
                this._xmlhttp.readyState = 3;
                break;
            case "complete":
                /*4/30/2009 Ajay reading from iframe is not straightforward. Evaluate nodes till you find a BODY tag*/
                var docobj=window.frames[this.id].document;
                var resTxt=""
                for (var j=0;j<docobj.childNodes.length ; j++ ){
					for (var k=0;k< docobj.childNodes[j].childNodes.length; k++ ){
							try{
								if (docobj.childNodes[j].childNodes[k].nodeName=='BODY'){
									resTxt+=docobj.childNodes[j].childNodes[k].innerHTML;
									g_log.debug('AJAX request IFRAME:: BODY TAG '+resTxt);
								}
							}
							catch (e){
								g_log.error('E07');
							}
						}
                }
				if (typeof(resTxt)=='undefined' || resTxt==null){
					g_log.error('E08');
					return;
				}
                resTxt = (resTxt.replace(/[\n\t\v\r\f]/g, ""));
                resTxt= resTxt.replace(/\&amp;/g,'&');
                this._xmlhttp.responseText=resTxt
                this.onreadystatechange = function(){}
                this._xmlhttp.readyState = 4;
                eval(this._xmlhttp._success+'(\''+resTxt+'\')');
                break;
        }   
    }
    else{
            eval(this._xmlhttp._fail+'(\'E06\')');
			g_log.error('E06');

    }
    
    if(typeof(this._xmlhttp.onreadystatechange) == "function")
            this._xmlhttp.onreadystatechange();
}
 

var g_log = new Logger("debug");
var trackval = queryString("debug");
if (trackval!=null)
{
    g_log.tracknow=((trackval=="true" || trackval==true)?true:false);
}



String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g,"");
}

String.prototype.ltrim = function() {
    return this.replace(/^\s+/,"");
}

String.prototype.rtrim = function() {
    return this.replace(/\s+$/,"");
}


// when calling this function, value stringSpecialCharsAllowed like this "%+-@" in the call
function _checkvalidstr(strCheck,strValidChars){
	var strChar;
   if (strCheck.length == 0) return false;
   strCheck = strCheck.toLowerCase();
    for (var i = 0; i < strCheck.length; i++){
        strChar = strCheck.charAt(i);
        if (strValidChars.indexOf(strChar) == -1){
            return false;
        }
    }
   return true;

}
function isNumeric(stringToCheck,  stringSpecialCharsAllowed)
{
   var strValidChars = "0123456789"+stringSpecialCharsAllowed;
   return  _checkvalidstr(stringToCheck,strValidChars);
 }

function isString(valueToCheck)
{
}

// when calling this function, value stringSpecialCharsAllowed like this "%+-+@" in the call
function isAlpha(stringToCheck, stringSpecialCharsAllowed)
{
   var strValidChars = " abcdefghijklmnopqrstuvwxyz"+stringSpecialCharsAllowed;
   return  _checkvalidstr(stringToCheck,strValidChars);
}

// when calling this function, value stringSpecialCharsAllowed like this "=-+@" in the call
function isAlphaNumeric(stringToCheck, stringSpecialCharsAllowed)
{
   var strValidChars = " abcdefghijklmnopqrstuvwxyz0123456789"+stringSpecialCharsAllowed;
   return  _checkvalidstr(stringToCheck,strValidChars);

}

function isNumber(field) 
{
    var re = /^[0-9-'.'-',']*$/;
    if (!re.test(field.value)) 
    { 
        field.value = field.value.replace(/[^0-9-'.'-',']/g,"");
    }
}
//sha1 one way hash
function HRBsha(msg)
{
var K = [0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6];
msg += String.fromCharCode(0x80);
var l = Math.ceil(msg.length/4) + 2;
var N = Math.ceil(l/16);
var M = new Array(N);
for (var i=0; i<N; i++) {
M[i] = new Array(16);
for (var j=0; j<16; j++) {
	M[i][j] = (msg.charCodeAt(i*64+j*4)<<24) | (msg.charCodeAt(i*64+j*4+1)<<16) |
			  (msg.charCodeAt(i*64+j*4+2)<<8) | (msg.charCodeAt(i*64+j*4+3));
	}
}
M[N-1][14] = ((msg.length-1)*8) / Math.pow(2, 32); M[N-1][14] = Math.floor(M[N-1][14])
M[N-1][15] = ((msg.length-1)*8) & 0xffffffff;

var H0 = 0x67452301;var H1 = 0xefcdab89;var H2 = 0x98badcfe;var H3 = 0x10325476;var H4 = 0xc3d2e1f0;
var W = new Array(80); var a, b, c, d, e;
for (var i=0; i<N; i++) {
for (var t=0;  t<16; t++) W[t] = M[i][t];
for (var t=16; t<80; t++) W[t] = ROTL(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1);
a = H0; b = H1; c = H2; d = H3; e = H4;
for (var t=0; t<80; t++) {
	var s = Math.floor(t/20); 
	var T = (ROTL(a,5) + f(s,b,c,d) + e + K[s] + W[t]) & 0xffffffff;
	e = d;
	d = c;
	c = ROTL(b, 30);
	b = a;
	a = T;
}
H0 = (H0+a) & 0xffffffff;
H1 = (H1+b) & 0xffffffff;
H2 = (H2+c) & 0xffffffff;
H3 = (H3+d) & 0xffffffff;
H4 = (H4+e) & 0xffffffff;
}
return H0.toHexStr() + H1.toHexStr() + H2.toHexStr() + H3.toHexStr() + H4.toHexStr();
}
function f(s, x, y, z){
	switch (s) {
	case 0: return (x & y) ^ (~x & z);   
	case 1: return x ^ y ^ z;
	case 2: return (x & y) ^ (x & z) ^ (y & z); 
	case 3: return x ^ y ^ z;  
	}
}

function ROTL(x, n){
return (x<<n) | (x>>>(32-n));
}

Number.prototype.toHexStr = function(){
var s="", v;
for (var i=7; i>=0; i--) { v = (this>>>(i*4)) & 0xf; s += v.toString(16); }
return s;
}


/*
 Pixels to be triggered is defined as a JSON object
 The identification of page is either based on a 
 token passed or based on the current URL
*/
function processPixelTracking(_token){

	var exclude = new Array('/espanol/','/puerto_rico/');
	var _url_or_token=null;
	if (typeof _token != 'undefined' && _token!=null && _token!=''){
		_url_or_token=_token;
	}else if (typeof location.pathname != 'undefined' || location.pathname!=null){
		_url_or_token=location.pathname;
		if (_url_or_token.indexOf('/')!=-1 && _url_or_token.indexOf('.html') == -1){
			_url_or_token=_url_or_token+'index.html';
		}
		//patch for taxtips article, detect if the page is TTIP article
		if (location.href.indexOf('ttiptitle') != -1){
			if (typeof g_tax_tip_id !='undefined'){
				_url_or_token='TAXTIP';
			}
		}
	}
	
	var pixel_obj = {
	 _pixelobj: [

		
		{pagetoken:'/taxes/office/pi_form.html',pixel:['018.html']},
		{pagetoken:'/espanol/curso_de_impuestos/index.html', pixel:['021.html','026.html']},
		{pagetoken:'/tax-software/back-editions.html', pixel:['022.html']},
		{pagetoken:'/tax-software/basic.html', pixel:['022.html']},
		{pagetoken:'/tax-software/current-state-update-forms.html', pixel:['022.html']},
		{pagetoken:'/tax-software/current-update-forms.html', pixel:['022.html']},
		{pagetoken:'/tax-software/deluxe.html', pixel:['022.html']},
		{pagetoken:'/tax-software/download-updates.html', pixel:['022.html']},
		{pagetoken:'/tax-software/index.html', pixel:['022.html']},
		{pagetoken:'/tax-software/mac.html', pixel:['022.html']},
		{pagetoken:'/tax-software/premium.html', pixel:['022.html']},
		{pagetoken:'/tax-software/premium-business.html', pixel:['022.html']},
		{pagetoken:'/tax-software/special-offers.html', pixel:['022.html']},
		{pagetoken:'/tax-software/state-editions.html', pixel:['022.html']},
		{pagetoken:'W2_TESTONLY', pixel:['014.html','017.html','002.html']},
		{pagetoken:'W2_GO',pixel:['011.html']},
		{pagetoken:'W2_SUCCESS',pixel:['012.html']},
		{pagetoken:'W2_FAILURE',pixel:['013.html']},
		{pagetoken:'TE2009',pixel:['004.html']},
		{pagetoken:'WIDGET',pixel:['005.html']},
		{pagetoken:'EMAIL_DISCOUNT',pixel:['006.html']},
		{pagetoken:'DEDUCTION_FINDER',pixel:['007.html']},
		{pagetoken:'LIFE_TAXES',pixel:['008.html']},
		{pagetoken:'TCO_LOGIN',pixel:['tco_login.html']},
		{pagetoken:'/taxes/planning/tax_courses/course_schedule.html',pixel:['023.html']},
		{pagetoken:'/espanol/curso_de_impuestos/course_schedule.html',pixel:['024.html']},
		{pagetoken:'/taxes/planning/tax_courses/index.html',pixel:['025.html']}
		
	
	 ],

	 getPixels:function(_url_or_token){
		

		 for (var i=0;i< this._pixelobj.length;i++ ){
			if (this._pixelobj[i].pagetoken==_url_or_token){

					if (typeof (this._pixelobj[i].exclusion) != 'undefined'){

						for (var k=0;k< this._pixelobj[i].exclusion.length;k++ ){
							var regex = new RegExp(this._pixelobj[i].exclusion[k]);
							if (location.pathname.match(regex)!=null){
								//alert('match found in exclusion list')
								return null;
							}
						}

					}
					if(typeof (this._pixelobj[i].env) == 'undefined' ){
						 return this._pixelobj[i].pixel;
					}
					else{
						var _env=g_sys.checkEnv();
						var _envpx =new Array();
						for (var k=0;k< this._pixelobj[i].env.length;k++ ){
							if(_env==this._pixelobj[i].env[k]|| this._pixelobj[i].env[k]=='ALL'){
							_envpx[_envpx.length]=this._pixelobj[i].pixel[k];
							}
						}
						return _envpx;
					}

				}
			}

			return null;
		}
	}
	
	// create a empty div
	var pixDiv = document.createElement("div");
	pixDiv.setAttribute("id", "hrb_pixel_tracker_div");
	//pixDiv.style.display='none';
	pixDiv.style.width='0px';
	pixDiv.style.height='0px';

	document.body.appendChild(pixDiv);

	//fetch the	generic pixels(to be run for all pages)
	var pixel_arr_gen = pixel_obj.getPixels('GENERIC');
	
	var pixel_arr = pixel_obj.getPixels(_url_or_token)
	if (pixel_arr!=null){
		//concat the pixel(s) for the token


		if (pixel_arr_gen!=null){
			pixel_arr=pixel_arr_gen.concat(pixel_arr);
		}
		
	}else{
		pixel_arr=pixel_arr_gen;
	}

	if (pixel_arr!=null){
		for (var i=0;i<pixel_arr.length ;i++ ){
			if (pixel_arr[i]!=null)	{
				var _ifobj= pixelCreateIFrame(pixel_arr[i]);
				pixDiv.appendChild(_ifobj);
			}

		}
	}
}
function createIframe(_frameURL,_attr){
	var rand_frameid = 'pixel_frame_'+parseInt(Math.random()*100)
   	var iframe = document.createElement("IFRAME");

	if (typeof _attr =='undefined' || _attr==null)
	{ 
		iframe.style.width='30px';
		iframe.style.height='0px';
		iframe.style.border='0px';
		iframe.width='30px';
		iframe.height='0px';

	}
	else{
		iframe.style.width=_attr.w+'px';
		iframe.style.height=_attr.h+'px';
		iframe.width=_attr.w+'px';
		iframe.height=_attr.h+'px';
		if (typeof _attr.b !='undefined'){
				iframe.style.border=_attr.b+'px';
				iframe.frameBorder=_attr.b;
		}
		else{
				iframe.style.border='0px';
				iframe.frameBorder=0;
		}
		if (typeof _attr.s !='undefined'){
					iframe.scrolling=(_attr.s==1)?"yes":"no";
		}
		else{
				iframe.style.scrolling='no';
		}
	}
	iframe.id = rand_frameid;
	iframe.src=_frameURL; 

	return iframe;
}

function pixelCreateIFrame(_frameURL){
		_frameURL = "/includes/pixel/pix_"+_frameURL;
		return createIframe(_frameURL);
}

function removeChildNodes(_obj){
// todo make this recursive
if ( typeof (_obj) != "undefined" && _obj != null){
	if ( typeof (_obj.childNodes[0]) != "undefined" && _obj.childNodes[0] != null){
			_obj.removeChild(_obj.childNodes[0]);
		}
	}
}


/********************************************************************
 JSON  toString function
**********************************************************************/

var typobj = {"boolean":function(){return Boolean},
            "function":function(){return Function},
            "number":function(){return Number},
            "object":function(o){return o instanceof o.constructor?o.constructor:null},
            "string":function(){return String},
            "undefined":function(){return null}
       }

function jsonToString(){

		var self = arguments.length ? arguments[0] : null,
			result, tmp;


		if(self === null){
			result = "null";
		}
		else if(self !== undefined && (tmp = typobj[typeof self](self))) {
			switch(tmp){
				case    Array:
					result = [];
					for(var i = 0, j = 0, k = self.length; j < k; j++) {
						if(self[j] !== undefined && (tmp = jsonToString(self[j]))){
							result[i++] = tmp;
						}
					};
					result = "[".concat(result.join(","), "]");
					break;
				case    Boolean:
					result = String(self);
					break;
				case    Date:
					break;
				case    Function:
					break;
				case    Number:
					result = isFinite(self) ? String(self) : "null";
					break;
				case    String:
					result = '"'.concat(self, '"');
					break;
				default:
					var i = 0, key;
					result = [];
					for(key in self) {
						if(self[key] !== undefined && (tmp = jsonToString(self[key]))){
							result[i++] = ''.concat(key, ':', tmp);
						}
					};
					result = "{".concat(result.join(","), "}");
					break;
			}
		}
		return result;
	}

	/****************************************************************************
		Personalization cookie
	*****************************************************************************/
g_per_cookie = {
	_cookieObj: null,

	initialize:function(){
	 this._cookieObj=null
	},
	updateCookie: function(){

	},
	getInfo: function (mod, year){

	},
	getProductInfo: function (pid,year){
		return getInfo("p",year);
	},
	updateProductInfo: function(pid,year,status){
	
	}

}

function getPageXref(product_id)
{	
	// The caller must know to use /taxes/partner/product.jsp?productId=xx,
	// not the value returned from this function, if on a tunneled page.
	var xref = {
	"30":{"url":"/online-tax-preparation/basic.html"},
	"31":{"url":"/online-tax-preparation/index.html"},
	"32":{"url":"/online-tax-preparation/premium.html"},
	"33":{"url":"/online-tax-preparation/best-of-both.html"},
	"34":{"url":"/tax-software/index.html"},
	"36":{"url":"/tax-software/premium.html"},
	"38":{"url":"/tax-software/premium-business.html"},
	"39":{"url":"/tax-software/state-editions.html"},
	"40":{"url":"/online-tax-preparation/index.html"},
	"44":{"url":"/taxes/products/44.html"},
	"64":{"url":"/offices/index.html"},
	"65":{"url":"/offices/tax-office-products-services.html"},
	"199":{"url":"/tax-software/basic.html"},
	"201":{"url":"/online-tax-preparation/free-edition.html"},
	"204":{"url":"/online-tax-preparation/deluxe.html"},
	"206":{"url":"/tax-software/deluxe.html"},
	"207":{"url":"/tax-software/deluxe.html"}
	};

	var destUrl=null;

	try
	{
		destUrl	=  xref[product_id].url;
	}
	catch (e)
	{
	}
	
	return destUrl;		// returns null if not match not found
}

