﻿/*
  JS-Code fuer FAZGETS-Tag. Muss einfach nur eingebunden werden um 'Standard'-PI's zu messen. Am Besten ganz am Anfang der Seite
  als erster JS-Include im HEAD. 

  Allgemeine Variablen:
  t (type) = pi|ti|cl|ka|ld
  
  PI-Variablen:
    t:      'pi'
    u:      url (location.href)
    r:      referrer (document.referrer)
    l:      userkey (Benutzerschluessel - Ergebnis der Funktion __GETSFL() falls diese definiert ist.
    c:      cookie-status
    p:      ContentPfad aus Meta-Tag "category"
    ct:     ContentType aus Meta-Tag "contenttype"
    ses:    Sessionkey (Sitzungsschluessel des Portals - Ergebnis der Funktion __GETSFS() falls diese definiert ist.
    tle:    Seitentitel
    ekeys:  Keyword-liste aus Meta-Tag "keywords"
    epers:  Personen-liste aus Meta-Tag "persons"
    elocs:  Ortsnamen-Liste aus Meta-Tag "locations"
    estks:  Wertpapier-Liste aus Meta-Tag "stocks"

    Nur bei erstem PI (wenn kein Session-Cookie gefunden):
    fsh:    Flash-Version 
    res:    Bildschirmaufloesung  
    js:     Javascript (=1) falls enabled

  TI-Variablen:
    t:      'ti'
    td:     TeaserData - tildeseparierte Liste von Teasern mit (tid~pos~title)-tupeln
    Infos aus dem PI-Objekt der Seite:
    u:      url (location.href)
    p:      ContentPfad aus Meta-Tag "category"

  Click-Variablen
    t:      'cl'
    cc:     ClickCoordinates (Mouseposition bei Klick in der Form xpos/ypos)
    ec:     ElementCoordinates (Koordinaten des ausloesenden Teaser-Divs, bzw. des Ankers, falls kein Teaser gefunden; in der Form x0/y0/w1/h1)
    hr:     Linkziel (href des Ankers kann auch javascript: sein!)
    Falls Teaserdaten vorhanden (div mit class=__GETS):
    tid     teaser-id/pfad
    pos     metaposition des Teasers (name)
    tle     Titel des Teasers
    Infos aus dem PI-Objekt der Seite:
    u:      url (location.href)
    p:      ContentPfad aus Meta-Tag "category"

  Keep-Alive-Variablen:
    t:      'ka'
        
*/

//Config
window.__GETSCFG = window.__GETSCFG || {
  autopi: true,       //pi wird automatisch ausgeloest
  autoti: true,       //teaser-impressions werden automatisch ausgeloest
  keepalive: false,   //keepalive aktivieren?
  loadtime: false,    //Seitenladezeit übermitteln?
  klickmode: 'off'  //smart = mit mousedown/click, off:kein klicktracking, soft:mit window.onclick, post:PostKlick-Klickparams am URL
};

//Erstmal ueberschreiben (vermeidet falsche fehler im Firebug)
window.__GETSFL = function(){return '';};
window.__GETSFS = function(){return '';};

var __GETS = {
  ver: 302,   //Versionsnummer
  base: 'ts.faz.net/ts/u.aspx',  //base-URL
  lim: 1950,  //maxlen eines querystrings (ab der in multipackets gesplittet wird)
  ki: 60,     //keep-alive-interval (in seconds)

  init: function(){
    W=window; T=this;
    if (T.inited) return; // schon initialisiert
    
    if(__GETSCFG.klickmode == 'smart' || __GETSCFG.klickmode=='post') T.addEvent(document, 'mousedown', W.__GETS.ctmd);
    if(__GETSCFG.klickmode == 'soft') T.addEvent(document, 'click', W.__GETS.ctclk);
    if(__GETSCFG.keepalive) setTimeout('__GETS.ka();', T.ki*1000);
    T.inited=1;
    if (__GETSCFG.autopi) this.tag();
  },

  tag: function(d){
    W=window; S=screen; C=document.cookie; D=document; T=this;
    
    //Cookie-state ermitteln
    c=0;
    if (C.indexOf('sgets=')>=0) c+=1;
    if (C.indexOf('pgets=')>=0) c+=2;

    //Login ermitteln (client muss eine __GETSFL definiert haben!
    L=''; SES='';
    try{ L=W.__GETSFL(); } catch(e) {}
    try{ SES=W.__GETSFS(); } catch(e) {}

    d = W.__GETSD || {};
    d.t = 'pi';
    d.u = d.u || location.href.split('#')[0];
    d.r = d.r || D.referrer.split('#')[0];
    d.l = d.l || L;
    d.c = c; //Cookie state
    d.ses = d.ses || SES; //Session
    d.tle = D.title;

    //js, flash und res nur bei Beginn der Session senden
    if ( (c&1)==0){
      d.fsh = T.gflash();
      d.res = S.width + '/' + S.height + '/' + S.colorDepth;
      d.js = 1; //EINS!
    }

    //Entities und Kategorie auslesen
    a = D.getElementsByTagName('meta');
    o={};
    for(i=0; i<a.length; i++) {
      if (a[i].name=='category') {
        d.p = a[i].content;
      } else if (a[i].name=='contenttype') {
        d.ct = a[i].content;
      } else if (a[i].name=='keywords') {
        o.ekeys = o.ekeys || [];
        o.ekeys.push(a[i].content);
      } else if (a[i].name=='persons') {
        o.epers = o.epers || [];
        o.epers.push(a[i].content);
      } else if (a[i].name=='locations') {
        o.elocs = o.elocs || [];
        o.elocs.push(a[i].content);
      } else if (a[i].name=='stocks') {
        o.estks = o.estks || [];
        o.estks.push(a[i].content);
      }
    }
    for(k in o) d[k]=o[k].join(',').replace(/ *, */g, '~');

    //abschick!
    T.page = d;
    T.send(d);
  },
  
  //extended tag. Benutzt die gegebene payload, erweitert sie um die props in ext und sendet das ganze
  etag: function(ext){
    T=this;
    o = T.page || {};
    for(key in ext) o[key] = ext[key];
    T.send(o);
  },
    
  //Uebermittelt Teaserliste. td ist Liste mit Teaserdaten: 
  //"tid|rub1/rub2/1234|tp|Homepage/Top1|tt|Das ist der Titel|r|nwl://politik/neu"
  ti: function(td){
    T=this;
    d = {}; 
    d.t = 'ti';
    d.td = td || '';
    if (d.td=='') return; //keine Liste -> kein Event
    p = T.page || {};
    if (p.u) d.u = p.u;
    if (p.p) d.p = p.p;
    T.send(d);
  },
  
  //Keep-Alive: alle 3 Minuten wird die Session aufrecht erhalten solange das Fenster auf ist
  ka: function(){
    T=this;
    d={};
    d.t='ka';
    T.send(d);
    if(__GETSCFG.keepalive) setTimeout('__GETS.ka();', T.ki*1000);
  },
  
  //version|packetid|packetnum|maxpackets|cp|login|cookie|site|script|res|payload|thisurl|refurl|targeturl|ip|useragent|clientid
  //Sendet das Datenobjekt d sowie die Events in e
  pack: function(d,e){
    T=this;
    a=[];
    for(k in d) {
      v=T.enc(d[k]);
      if (v=='') continue;
      a.push(k); 
      a.push(v);
    };
    h='?3|'+Math.floor(Math.random()*1000000000)+'|';
    s=a.join('|');
    b=[];
    L=T.lim;
    while(s.length>L){
      b.push(s.substr(0,L));
      s=s.substr(L);
    }
    if (s.length>0) b.push(s);

    for(i=0; i<b.length; i++) b[i] = location.protocol+"//"+T.base+h+(i+1)+"|"+b.length+"|"+b[i];
    return b;
  },
  
  send: function(d){
    b=this.pack(d);
    for(i=0; i<b.length; i++) {
      x=new Image();
      x.src=b[i];
    }
  },
  
  //Server-Encoding: die Zeichen | und + haben besondere Bedeutung, daher urlencoded Darstellung
  //Blank wird mit "+" replaced. Ansonsten bleibt alles wies is.
  enc:function(v){
    if (v==null) return '';
    v=''+v;

    //string "reinigen" und umlaute manuell encoden
    v=v.replace(/[^a-zA-Z0-9äöüßÄÖÜ\|\.\-\$\(\)\{\}\[\]\+\!\?_\/ %@,;~&%:=]/g, '');
    v=v.replace(/ä/g, '\\a');
    v=v.replace(/ö/g, '\\o');
    v=v.replace(/ü/g, '\\u');
    v=v.replace(/ß/g, '\\s');
    v=v.replace(/Ä/g, '\\A');
    v=v.replace(/Ö/g, '\\O');
    v=v.replace(/Ü/g, '\\U');
    v=v.replace(/[|]/g, '\\p');
    v=v.replace(/[ ]/g, '^');
    return v;
  },

  //Ermittelt die Koordinaten eines Elements und liefert x1,y1,x2,y2 als string
  gc: function(el){
    if (!el) return '';
    var w = parseInt(el.offsetWidth);
    var h = parseInt(el.offsetHeight);
    var l = 0; var t = 0;

		do {
			l += el.offsetLeft || 0;
			t += el.offsetTop || 0;
			el = el.offsetParent;
		} while (el);
    a=[l, t, l+w, t+h];
    return (a.join('/'));
  },
  
  addEvent: function ( obj, type, fn ){
     if (obj.addEventListener) {
        obj.addEventListener( type, fn, false );
     } else if (obj.attachEvent) {
        obj['e'+type+fn] = fn;
        obj[type+fn] = function() { obj['e'+type+fn]( window.event ); };
        obj.attachEvent( 'on'+type, obj[type+fn] );
     }
  },
  
  cancelEvent: function (e){
    e = e || window.event;
    if(e.stopPropagation) e.stopPropagation();
    if(e.preventDefault) e.preventDefault();
    e.cancelBubble = true;
    e.cancel = true;
    e.returnValue = false;
    return false;
  },

  //Muss auf den Mousedown des Windows gelegt werden. Falls ein <a href...> Ausloeser ist
  //UND eine http-, https-Adresse ODER ein javascript-Call im href stehen 
  //wird das Klicktracking aktiviert (Erzeuge Klick-Event auf dem Element, der abbrechbar ist) 
  ctmd: function(ev){
    ev = ev || window.event; 
    if (!ev) return;
    el = ev.target? ev.target : ev.srcElement;
    if (!el) return;

    while(el.tagName!='A' && el.tagName!='BODY') el=el.parentNode;
    if (!el || el.tagName!='A' || !el.href || el.hasGetsClick || location.href==el.href || el.href=='#' || (el.href.indexOf('http')!=0 && el.href.indexOf('javascript:')!=0)) return;
    
    if (__GETSCFG.klickmode=='smart'){
      G = window.__GETS;
      G.addEvent(el, 'click', G.ctclk);
      el.hasGetsClick=true;
    } else if (__GETSCFG.klickmode=='post'){
      app = (el.href.indexOf('?')>0)? "&": "?";
      el.href += app+"la=li&hi=he";
    }
  },

  //Wird vom Mousedown auf einem A-Tag registriert. Bricht den eigentlichen Klickevent ab und fuehrt dann
  //den href oder das javascript im href aus. Wird NUR(!) ausgefuehrt wenn im href 'http' oder 'javascript'
  //am Anfag steht!
  ctclk: function(ev){
    ev = ev || window.event;
    if (!ev) return;

    el = ev.target? ev.target : ev.srcElement;
    if (!el) return;
    
    while(el.tagName!='A' && el.tagName!='BODY') el=el.parentNode;
    if (!el || el.tagName!='A' || !el.href || location.href==el.href || el.href=='#' || (el.href.indexOf('http')!=0 && el.href.indexOf('javascript:')!=0)) return;

    G = window.__GETS;
    if (__GETSCFG.klickmode == 'smart') G.cancelEvent(ev);

    hr = el.href || '';
    x = ev.pageX || ev.clientX + document.documentElement.scrollLeft;
    y = ev.pageY || ev.clientY + document.documentElement.scrollTop;
    
    //Teaser-Daten ermitteln (finde vorhergehendes DIV mit class="__GETS" oder breche bei BODY ab.
    ecord = G.gc(el);
    while(el && el.tagName!='DIV' && el.tagName!='BODY' && el.className!='__GETS') el=el.parentNode; 

    //Basisdaten fuer Klick
    d={
      t:'cl',
      cc: x+'/'+y,
      hr: hr
    };
    
    //Falls Teaserdaten vorhanden, dann erweitern
    if (el.className=='__GETS' && el.attributes['name']) {
      a = el.attributes['name'].nodeValue.split('~');
      L = a.length;
      if (L>0) d.tid = a[0];
      if (L>1) d.pos = a[1];
      if (L>2) d.pos = a[2];
      ecord = G.gc(el);
    }
    d.ec=ecord;

    //Falls Pagedaten vorhanden, dann erweitern
    p = G.page;
    if (p.u) d.u=p.u;
    if (p.p) d.p=p.p;

    //Daten zusammenpacken.
    b = G.pack(d);
    if (b.length>1) return true; //nix machen, wenn mehr als 1 Image zu laden Maybe FIXME?
    
    //Tag absetzen und href setzen, wenn href ein JS-call ist
    var img = new Image();
    if (hr.indexOf('javascript:')==0 || __GETSCFG.clickmode=='soft'){
      img.src=b[0];
      location.href=hr;
      return true;
    }

    //Ansonsten timeout setzen und href aendern wenn Pixel geladen oder 300ms Timeout vorbei
    W=window;
    cmd = "location.href='"+hr+"'";
    W.gctmr=W.setTimeout(cmd, 300);
    img.onload=function(){location.href=hr;};
    img.src=b[0];
    return false;
  },
  
  //Detected Flash-Version
  gflash: function () {
    if (location.protocol=='https') return '';
    
    // Flash Player Version Detection - Rev 1.5
    // Detect Client Browser type
    // Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved.
    var N = navigator;
    var isIE  = (N.appVersion.indexOf("MSIE") != -1) ? true : false;
    var isWin = (N.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
    var isOpera = (N.userAgent.indexOf("Opera") != -1) ? true : false;

    // NS/Opera version >= 3 check for Flash plugin in plugin array
	  var flashVer = -1;
  	
	  if (N.plugins != null && N.plugins.length > 0) {
		  if (N.plugins["Shockwave Flash 2.0"] || N.plugins["Shockwave Flash"]) {
			  var swVer2 = N.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
			  var flashDescription = N.plugins["Shockwave Flash" + swVer2].description;			
			  var descArray = flashDescription.split(" ");
			  var tempArrayMajor = descArray[2].split(".");
			  var versionMajor = tempArrayMajor[0];
			  var versionMinor = tempArrayMajor[1];
			  if ( descArray[3] != "" ) {
				  tempArrayMinor = descArray[3].split("r");
			  } else {
				  tempArrayMinor = descArray[4].split("r");
			  }
			  var versionRevision = tempArrayMinor[1] > 0 ? tempArrayMinor[1] : 0;
			  var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
		  }
	  }
	  // MSN/WebTV 2.6 supports Flash 4
	  else if (N.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
	  // WebTV 2.5 supports Flash 3
	  else if (N.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
	  // older WebTV supports Flash 2
	  else if (N.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
	  else if ( isIE && isWin && !isOpera ) {
      var version;
      var axo;
      var e;

      try {
        // version will be set for 7.X or greater players
        axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
        version = axo.GetVariable("$version");
      } catch (e) {}

      if (!version)
      {
        try {
          // version will be set for 6.X players only
          axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
          
          // installed player is some revision of 6.0
          // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
          // so we have to be careful. 
          
          // default to the first public version
          version = "WIN 6,0,21,0";

          // throws if AllowScripAccess does not exist (introduced in 6.0r47)		
          axo.AllowScriptAccess = "always";

          // safe to call for 6.0r47 or greater
          version = axo.GetVariable("$version");

        } catch (e) {}
      }

      if (!version)
      {
        try {
          // version will be set for 4.X or 5.X player
          axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
          version = axo.GetVariable("$version");
        } catch (e) {}
      }

      if (!version)
      {
        try {
          // version will be set for 3.X player
          axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
          version = "WIN 3,0,18,0";
        } catch (e) {}
      }

      if (!version)
      {
        try {
          // version will be set for 2.X player
          axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
          version = "WIN 2,0,0,11";
        } catch (e) {
          version = "";
        }
      }
      
      flashVer=version;
    }	
    flashVer+=''; //toString
	  return flashVer.replace(/,/gi, '.');
  },

  //domready-event:
  dr: function(){
    if (__GETS.dr_fired) return;
    __GETS.dr_fired=1;
    
    //Der eigentliche DomReady - suche Teaser!
    if (!__GETSCFG.autoti) return;
    a=document.getElementsByTagName('div');
    b=[];
    for(i=0; i<a.length; i++) {
      if (a[i].className!='__GETS') continue;
      s='';
      try{ s=a[i].attributes['name'].nodeValue; } catch(e) {}
      b.push(s);
    }
    s = b.join('~');
    this.ti(s);
  },
  
  //onload der Seite. Macht Messung über Ladezeit der Seite
  load: function(){
    W=window; T=this;
    if (!W.__GETStmr || !__GETSCFG.loadtime) return;
    
    now = new Date();
    time = now.valueOf() - W.__GETStmr.valueOf();
    d = {t:'ld', ldtime:time};
    p = T.page || {};
    if (p.u) d.u = p.u;
    if (p.p) d.p = p.p;
    T.send(d);
  }
};

//DomReady handling fuer FF, IE, Safari, Opera registrieren.
//ACHTUNG! 26.01.2008: Nur registrieren, wenn kein https. IE mag das nicht bei https-Verbindungen!
if (location.protocol=='http')
{
  if (document.addEventListener) {
    document.addEventListener("DOMContentLoaded", function(){__GETS.dr();}, false);
  } else if (/Safari/i.test(navigator.userAgent)) {
    __GETS.dr_timer = setInterval(function() {
      if(/loaded|complete/.test(document.readyState)) {
        clearInterval(__GETS.dr_timer);
        __GETS.dr();
      }
    }, 10);
  } else if (document.all && !window.opera) {
    document.write('<script type="text/javascript" id="GETSDR" defer="defer" src="javascript:void(0)"><\/script>');
    document.getElementById("GETSDR").onreadystatechange=function(){
      if (this.readyState=="complete") __GETS.dr();
    };
  };
}

//Failsafe, falls kein DomReady gefeuert
window.__GETS.addEvent(window, 'load', function(){
  setTimeout("__GETS.dr();", 0);
  __GETS.load();
});

//PI messen
__GETS.init();

