﻿///-----------------------------------------------------------------------------------
///	FileName: 	Tracking.js
///	Summary:	Tracking function
///				
///
///	ModifyDate:	2009/02/25
///	Author:	Winter Li
///				
/// Example:
///			initiate Omniture tracking with auto view:
///               Tracking.OMT.Init(new Array('my_channel','my_solution',true));        	
///
///			initiate Atlas tracking:
///               Tracking.Atlas.Init(new Array('my_country','my_basetag'));  
///
///			initiate Omniture tracking when window loaded:
///               _Register_Event("load",Tracking.OMT.Init,new Array('my_channel','my_solution',true));        	
///
///			initiate Atlas tracking when window loaded:
///               _Register_Event("load",Tracking.Atlas.Init,new Array('my_country','my_basetag'));  
///
///			send Atlas view tracking for 404 page:
///               Tracking.Action('Atlas_1|view|||404||||');
///
///			send Atlas action tracking:
///               Tracking.Action('Atlas_17|click|episode|video|homepage||||');
///
///			send Atlas action tracking with var:
///               Tracking.Action('Atlas_17|click|episode|video|homepage||||var1value|var2value');
///
///			send Omniture view tracking:
///               Tracking.Action('OMT_1|view||||');
///
///			send Omniture action tracking:
///               Tracking.Action('OMT_2|my_action|my_actionname|my_section|my_location|');    
///
///			send Omniture action tracking with prop:
///               Tracking.Action('OMT_3|my_action|my_actionname|my_section|my_location|13.prop13value|14.prop14value')
///
///			send DL expose tag with ID and Cache killer:
///               Tracking.Action('DL_2|http://amch.questionmarket.com/adsc/d453206/3/466081/randm.js','JS')
///
///			send DL expose tag without ID and Cache killer:
///               Tracking.Action('http://amch.questionmarket.com/adsc/d453206/3/466081/randm.js','JS',false)
///
///			send DL duration tag with ID and Cache killer:
///               Tracking.Action('DL_3|http://amch.questionmarket.com/adsc/d453206/3/466082/adscout.php')
///
///			send DL duration tag without ID and Cache killer:
///               Tracking.Action('http://amch.questionmarket.com/adsc/d453206/3/466082/adscout.php','IMG',false)
///
///	Other tips:
///         call Tracking.Debug=true; to open debug mode so that the error message will pop up when exception happens.
///
//------------------------------------------------------------------------------------ Config

var OMT_ID_PROP="28";//this prop represent the tracking id
var OMT_LINK_INTERNAL_FILTERS="javascript:,msn.com";
var OMT_SERVER="msn.com";
var OMT_DEFAULT_AUTOVIEW=false;

var ATLAS_VERSION="v3";    
var ATLAS_PREFIX="http://switch.atdmt.com/action/";
//Atlas tracking fired under these domains (keywords) will contain "test.test"
var ATLAS_TEST_SITES=new Array(
                        ".msn-int.com",
                        "localhost",
                        "msn-beetsh-dev"
                        );

var ATLAS_TEST_VALUE="test.test";

//------------------------------------------------------------------------------------ Constant

//the prefix of tracking ID
var MODE_ATLAS="ATLAS";
var MODE_DLTAG="DL";
var MODE_OMT="OMT";

//internal use only
var TYPE_IMG="IMG";//request it as an image
var TYPE_JS="JS";//add it as a js to header
var TYPE_FUN="FUN";//execute a js function
var TYPE_HTML="HTML";//append HTML to body

var Atlas_Segment=["action","actionname","section","location","time","videotime","videosession","var"];
var Atlas_Template="{PREFIX}{PROJECT}{VERSION}{LANGUAGE}{COUNTRY}{RESOLUTION}{SOURCE}{DOMAIN}{URL}{SEARCH}{KEYWORDS}";

var ImgTrackingQueue=new Array(); 
var IsImgLoaded=true;
var WaitingTimes=0;
var MaxWaitingTimes=10;//(MaxWaitingTimes * CheckInterval) is the max time you can bear for send one image tracking 
var CheckInterval=100;

var w=window;

//------------------------------------------------------------------------------------ for Queue the Image Tracking

function _CheckQueue()
{
    if(!IsImgLoaded)
    {
        if(WaitingTimes<MaxWaitingTimes)
        {
            WaitingTimes++;
            return;
        }else
        {
            IsImgLoaded =true;
            WaitingTimes=0;
        }
    }
    
    if(ImgTrackingQueue.length >0)
    {
        IsImgLoaded =false;
        WaitingTimes=0;
        
        var tv = ImgTrackingQueue.shift();
        var img = new Image();
        img.onload = function() {            
            IsImgLoaded=true;
        }
        img.onerror = function() {            
            IsImgLoaded=true;
        }
        img.src = tv;
    }     
}

//------------------------------------------------------------------------------------ for All Tracking

_Action = function(value)
{    
    var tv;
      
    var type=TYPE_IMG; 
    var ckey=true;
    
    if(arguments.length<1 || arguments[0].length<=0) 
    {
        if(Tracking.Debug)
        {
            alert("Tracking value is null.");
        }       
        return;        
    }
    
    if(arguments.length >=3)
    {
        if(!arguments[2])
            ckey =false;        
    }
    
    if(arguments.length >=2)
    {    
        if(arguments[1].toUpperCase()== TYPE_IMG||
            arguments[1].toUpperCase()== TYPE_JS||
            arguments[1].toUpperCase()== TYPE_FUN||
            arguments[1].toUpperCase()== TYPE_HTML)
        {
            type =arguments[1].toUpperCase();
        }
        else 
        {
            if(Tracking.Debug)
            {
                alert("Tracking type ["+arguments[1]+"] is not correct.");
            }
        }
                
    }
      
    
    var position=value.indexOf('|');
    var tid=value.substr(0,position);    
    var mode=tid.split('_')[0].toUpperCase();        
    var mv=value.substr(position+1);
    
    switch(mode)
    {
        case MODE_ATLAS:        
            tv=_Build_Atlas(tid,mv,ckey);   
            break;
        case MODE_OMT:
            tv=_Build_OMT(tid,mv);
            type =TYPE_FUN;
            break;
        default:
            if(type==TYPE_HTML||type==TYPE_FUN)
                tv=mv;
            else 
                tv=_Build_Other(tid,mv,ckey);
    }

    switch(type) 
    {
        case TYPE_IMG :     
            ImgTrackingQueue.push(tv); 
            break;
        case TYPE_JS:    
            _Add_JsFile(tid,tv);
            break;
        case TYPE_FUN:             
            eval(tv);                        
            break;
        case TYPE_HTML: 
            _Add_HTML(tid,tv);            
            break;    
        default:
            ImgTrackingQueue.push(tv); 
    }
    
}

_Build_Atlas = function(id,value,ckey)
{
    var prefix=_Get_Prefix(); 
    var finaltv;
    var tv=new Array();
    
    var seg = value.split('|');
    var maxLength = seg.length<Atlas_Segment.length ? Atlas_Segment.length :seg.length;
    
    for(i=0;i<maxLength;i++)
    {
        if(i<seg.length && seg[i].length>0)
        {
            if(i>=Atlas_Segment.length-1)
            {
                try{
                    var index=i-Atlas_Segment.length + 2;
                    tv.push(Atlas_Segment[Atlas_Segment.length-1]+index+"."+ _Clean_String(seg[i]) ); 
                }catch(e) 
                {
                    if(Tracking.Debug)
	                {
	                    alert("Error occured while building Atlas tracking."+e.message);
	                }    
                }
            }
            else
            {
                tv.push(Atlas_Segment[i]+"."+ _Clean_String(seg[i]) ); 
            }
        }        
    }
    
    finaltv =prefix +"id."+id +"/"+ tv.join("/");
    
    for(i=0;i<ATLAS_TEST_SITES.length ;i++)
    {
        if(window.location.host.indexOf(ATLAS_TEST_SITES[i])!=-1)
        {
            finaltv+= "/"+ ATLAS_TEST_VALUE+"/"
            break;
        }
    }
    
    if(ckey) 
        finaltv+="?"+Constant_Random();
        
    return finaltv ;
}

_Build_OMT=function(id,value)
{    
    return "_OMT_Action('"+id+"','"+value+"')";
}

_Build_Other=function(id,value,ckey)
{    
    value=_Do_Replace(value);    
    var finaltv=value;
    
    if(id.length>0)
    {
        if(finaltv.indexOf('?')!=-1)
            finaltv +="&id="+id;
        else 
            finaltv +="?id="+id;
    }
    if(ckey)
    {
        if(finaltv.indexOf('?')!=-1)
            finaltv +="&ord="+Constant_Random(); 
        else 
            finaltv +="?ord="+Constant_Random(); 
    }
    
    return finaltv;
}

_Get_Prefix = function ()
{
    var prefix = Atlas_Template;        
    return _Do_Replace(prefix);
}

_Do_Replace = function(value)
{
    var  tv= value;
    
    for(i=0;i<constants.length;i++)
    {       
        tv = tv.replace(constants[i].name, eval(constants[i].value)());
    }
    return tv;
}

_Get_TrackingValue=function(value)
{
    var position=value.indexOf('|');    
    var mv=value.substr(position+1,value.length-position);
    return mv;
}

//------------------------------------------------------------------------------------ Common function

_Add_HTML =function (id,code)
{	    
	var ne=document.createElement('div');	
    ne.innerHTML=code;
    ne.id =id;
    
    try{
        var oe = document.getElementById(ne.id);
        if(oe != null)
            document.body.removeChild(document.getElementById(ne.id));
        document.getElementsByTagName("body")[0].appendChild(ne);
	    
	}catch(e)
	{	
	    if(Tracking.Debug)
	    {
	        alert("Error occured while adding HTML code."+e.message);
	    }    
	}
}

_Add_JsFile =function (id,src)
{	    
	var ne=document.createElement('script');
    ne.setAttribute("type","text/javascript");
    ne.setAttribute("src", src);
    ne.id =id;    
    
    try{
        var oe = document.getElementById(ne.id);
        if(oe != null)
            document.body.removeChild(oe);
        document.getElementsByTagName("head")[0].appendChild(ne);
	    
	}catch(e)
	{	    
	    if(Tracking.Debug)
	    {
	        alert("Error occured while adding JS file."+e.message);
	    }
	}
	
}

_Clean_String =function( str )
{
    return str.replace( /\/|\?|&|\.|#|:/g, "_" );
}

_Register_Event=function(evt,func,varArray)
{
    if(typeof(window.addEventListener)!="undefined"){
        window.addEventListener(evt,Function(func(varArray)),false);
    }else
    {             
        window.attachEvent("on"+evt,Function(func(varArray)));
    }
} 

////------------------------------------------------------------------------------------ Atlas

_Atlas_Init=function (v)
{
    if(Tracking.Debug && v.length!=2)
    {
        alert("Length of parameter array is not correct for Tracking.Atlas.Init().");         
    }
    if(v.length>=1)
        Tracking.Atlas.Country=v[0];
    if(v.length>=2)    
        Tracking.Atlas.BaseTag=v[1];
}


//------------------------------------------------------------------------------------ Omniture

_OMT_Init=function(v)
{
    var channel="";
    var solution="";
    var autoView=OMT_DEFAULT_AUTOVIEW;
    
    if(Tracking.Debug && v.length!=3)
    {
        alert("Length of parameter array is not correct for Tracking.OMT.Init()");         
    }
        
    if(v.length>=1)
        channel=v[0];
    if(v.length>=2)
        solution=v[1];
    if(v.length>=3)
        autoView=v[2];
        
    if(!w.s)
    {
        w.s={};
    }        
        
    w.s.channel=channel;
    w.s.pageName=document.title;
    w.s.linkInternalFilters=OMT_LINK_INTERNAL_FILTERS;
    w.s.server=OMT_SERVER;
    w.s.prop1=solution;
        
    if(Constant_Language().split('.').length>1)
    {
        w.s.prop2=Constant_Language().split('.')[1].split('/')[0];
    }else 
    {
        if(Tracking.Debug)
        {
            alert("Exception happened when getting language.");             
        }
        
        w.s.prop2="en";        
    }
    
    if(typeof(autoView)!="undefined" && autoView)
    {     
        _OMT_View();
    }       
          
}

_OMT_View=function ()
{
    window.s.t();
}

_OMT_Action=function(id,value)
{    
    var seg=value.split('|');
    
    if(seg.length<5)
    {
        if(Tracking.Debug)
        {
            alert("Format of Omniture's tracking value is wrong."); 
        }    
        return;
    }
    // send view tracking
            
    if(seg[0].toUpperCase()=="VIEW")
    {
       eval("w.s.prop"+OMT_ID_PROP+"='"+id+"'");
       _OMT_View();
       eval("w.s.prop"+OMT_ID_PROP+"=''");
        return;
    }
    
    // set prop value    
    
    w.s.prop5= _Clean_String(seg[0]);    
    w.s.prop6= _Clean_String(seg[1]);    
    w.s.prop4= _Clean_String(seg[2]);    
    w.s.prop3= _Clean_String(seg[3]);
            
                
    for(i=4;i<seg.length;i++)
    {
        var vl=seg[i].split('.');
        if(vl.length>1)
        { 
            eval("w.s.prop"+vl[0]+"='"+ _Clean_String(vl[1]) +"'");
        }

    }
    
    w.s.prop9=w.s.prop3+"_"+w.s.prop5+"_"+w.s.prop6;
    w.s.prop10=w.s.prop4+"_"+w.s.prop5+"_"+w.s.prop6;
    
    eval("w.s.prop"+OMT_ID_PROP+"='"+id+"'");
    
    // send tracking
    
    w.s.tl();
    
    // clear prop value
    
    w.s.prop5 = w.s.prop6 = w.s.prop4 = w.s.prop3 = w.s.prop9 = w.s.prop10 = "";
      
    for(i=4;i<seg.length;i++)
    {
        var vl=seg[i].split('.');
        if(vl.length>1)
        { 
            eval("w.s.prop"+vl[0]+"=''");
        }
    }
    
    eval("w.s.prop"+OMT_ID_PROP+"=''");
    
}

    
//------------------------------------------------------------------------------------
//  
//  Tracking object defination
//
//------------------------------------------------------------------------------------

var Tracking={    
    Action:_Action,
    Atlas:{
        Init:_Atlas_Init,
        Country:"noCountry",
        BaseTag:"noProject"
    },
    OMT:{
        Init:_OMT_Init
    },
    SearchProviders:
    {
        Live   : { form : "http://search.live.com/results.aspx?", key : "q"  },
        Google : { form : "http://www.google.com/search?",        key : "q"  },
        Yahoo  : { form : "http://search.yahoo.com/search?",      key : "p"  },
        Ask    : { form : "http://www.ask.com/web?",              key : "q"  },
        Baidu  : { form : "http://www.baidu.com/s?",              key : "wd" }    
    },
    Debug:false     
}


setInterval( _CheckQueue,CheckInterval); 


//------------------------------------------------------------------------------------
//  
//  Below are the constant functions which will be used for replacing template content.
//
//------------------------------------------------------------------------------------
var constants=[

    {name:"{PREFIX}",value:"Constant_Prefix"},
    {name:"{PROJECT}",value:"Constant_Project"},
    {name:"{VERSION}",value:"Constant_Version"},
    {name:"{LANGUAGE}",value:"Constant_Language"},
    {name:"{COUNTRY}",value:"Constant_Country"},
    {name:"{RESOLUTION}",value:"Constant_Resolution"},        
    {name:"{SOURCE}",value:"Constant_Source"},    
    {name:"{DOMAIN}",value:"Constant_Domain"},
    {name:"{URL}",value:"Constant_Url"},
    {name:"{SEARCH}",value:"Constant_Search"},        
    {name:"{KEYWORDS}",value:"Constant_Keywords"},    
    {name:"{RANDOM}",value:"Constant_Random"}

];

function Constant_Prefix()
{
    return ATLAS_PREFIX;
}
function Constant_Project()
{       
    var rv="";
    
    rv+=Tracking.Atlas.BaseTag;
    
    rv+="/";
    return rv;
}
function Constant_Version()
{
    var rv="";
    
    rv+=ATLAS_VERSION;
    
    rv+="/";
    return rv;    
}
function Constant_Language()
{
    var rv="language.";
    
    var tv= navigator.language ?  navigator.language :  navigator.browserLanguage;
    
    return BuildValue(tv,rv);
    
}
function Constant_Country()
{    
    var rv="country.";
    
    var tv=Tracking.Atlas.Country;
    
    return BuildValue(tv,rv);
    
}
function Constant_Resolution()
{    
    var rv="resolution.";
    
    var tv= screen.width + "x" + screen.height;
    
    return BuildValue(tv,rv);
}
function Constant_Source()
{    
    var rv="source.";
    
    var tv=GetQuerystringValue("source");
    
    return BuildValue(tv,rv);
}

function Constant_Domain()
{
    var rv="domain.";
    
    var tv=GetDomain(document.referrer);
    
    return BuildValue(tv,rv);
}

function Constant_Url()
{
    var rv="url.";
    
    var tv=encodeURIComponent(document.referrer);
    
    return BuildValue(tv,rv);
}

function Constant_Search()
{
    var rv="search.";
    
    var tv=GetSearchResult(document.referrer);
    
    return BuildValue(tv,rv);
}

function Constant_Keywords()
{
    var rv="keywords.";
    
    var tv=GetSearchKeywords(document.referrer);
    
    return BuildValue(tv,rv);

}

function Constant_Random()
{
    return Math.floor((new Date()).getTime()/1000);
}


function BuildValue(tv,rv)
{
    if(tv.length!=0) 
    {
        return rv+tv+"/";
    }
    else 
    {
        return "";
    }    
}    

function GetQuerystringValue( s, u )
{
    s += "=";
    var h  = u ? u : window.location.href,
        ss = h.indexOf( s ),
        a  = "&",
        b  = "#";
    q = h.indexOf( '?' );
    if ( q > 0 && ss > q )
    {
        sh = h.substring( ss + s.length );
        if(sh.indexOf( a ) > 0 )
            sh=sh.substring( 0, sh.indexOf( a ));
        if(sh.indexOf( b ) > 0 )
            sh=sh.substring( 0, sh.indexOf( b )); 
            
        return sh;
    }
    return "";
}

function GetDomain(v)
{
    var regex  = "(?:http|https)://(.*?)/";
             
    if ( v && v.length > 0 )
    {
        var matches = v.match( regex );
        
        if ( matches && matches.length > 1 )
        {
            return encodeURIComponent( matches[1] );
        }
    }
    
    return "";
} 

function GetSearchResult(v)
{   
    for ( var search in Tracking.SearchProviders)
    {   
        if ( v.indexOf( Tracking.SearchProviders[ search ].form ) == 0 )
        {                
            return search;
        }
    }
    return "";
}

function GetSearchKeywords(v)
{        
    for ( var search in Tracking.SearchProviders)
    {
        if ( v.indexOf( Tracking.SearchProviders[ search ].form ) == 0 )
        {                
            return GetQuerystringValue( Tracking.SearchProviders[ search ].key, v ).replace( /[+]/g, "," );
        }
    }    
    return "";
}
//------------------------------------------------------------------------------------ End