var Tracker = (function(){

// Private Methoden/Properties ############################################################################


	/* --- Mapping von Klarnamen zu Omniture-Variablen -------------------- */
	/* --- Events --- */
	var _events = {
		"Product" : "prodView",
		"Shopping Cart Open" : "scOpen",
		"Shopping Cart Checkout" : "scCheckout",
		"Purchase" : "purchase",
		"Page View" : "event1",
		"Form Error" : "event2",
		"checkAvailability" : "event3",
		"Check Availability" : "event3",
		"Popup Newsletter" : "event4",
		"Popup Feedback" : "event5",
		"Popup Callback" : "event6",
		"DSL DB Optin" : "event7",
		"Newsletter First Optin" : "event8",
		"Newsletter Second Optin" : "event9",
		"Newsletter Optout" : "event10",
		"Contact Form Sent" : "event11",
		"Intern Search" : "event12",
		"Registration" : "event13",
		"Activation" : "event14",
		"Login" : "event15",
		"Password Request" : "event16",
		"Change EMail" : "event17",
		"Change Personal Data" : "event18",
		"Change Contact Data" : "event19",
		"Change Bank Data" : "event20",
		"Change Invoice Type" : "event21",
		"Change Invoice Adress" : "event22",
		"Change billingAddress Data" : "event22",
		"Change Advertising" : "event23",
		"Authentification" : "event24",
		"costOverview" : "event25",
		"Cost Overview" : "event25",
		"Teaser View" : "event26",
		"Teaser Click" : "event27",
		"Open Video Catalog" : "event29",
		"Change deliveryAddress Data" : "event30",
		"Change Delivery Adress" : "event30",
		"Change Einzelverbindung" : "event31",
		"SmartCard Activation" : "event32",
		"Stoerungsmeldung" : "event33",
		"Registration Rechnung Online" : "event34",
		"SIM-Karte aktivieren" : "event35",
		"Retourenschein erstellen" : "event36",
		"Sicherheitspaket kuendigen" : "event37",
		"Zahlungsweg aendern" : "event38",
		"Umzugsservice" : "event39",
		"Programmbelegung" : "event40",
		"DSLWechselschreiben" : "event41",
		"Wechselerinnerung" : "event42",
		"Verfuegbarkeitspruefung" : "event43",
		"Haendlersuche" : "event44",
		"CleverPro" : "event45",
		"Hausanschluss" : "event46",
		"Stoerung PLZ" : "event47",
		"Stoerung Auswahl" : "event48",
		"Stoerung FAQ" : "event49",
		"Stoerung Formular": "event50"
	};
	/* --- Traffic Variablen --- */
	var _trafficVars = {
		"Visitor Name Space" : "visitorNamespace",
		"Report Suite" : "account",
		"Tracking Server" : "dc",
		"Page Name" : "pageName",
		"Channel" : "channel",
		"Subsection" : "prop1",
		"extendes Pagename" : "prop2",
		"Extended Page Name" : "prop2",
		"Prospect" : "prop3",
		"prop4" : "prop4",
		"Campaign Path" : "prop5",
		"Page Type" : "pageType"
	};
	/* --- Conversion Variables --- */
	var _eVars = {
		"Campaign" :  "campaign",
		"Products" : "products",
		"Purchase ID" : "purchaseID",
		"Prospect" : "eVar1",
		"ChatAvailable" : "eVar2",
		"Intern Search Term" : "eVar3",
		"ZipCode" : "eVar4",
		"CustomerType" : "eVar5",
		"VPNr" : "eVar6",
		"Page Name" : "eVar7",
		"Error Code" : "eVar8",
		"Availability" : "eVar9",
		"Initial VPNr" : "eVar10",
		"Discount" : "eVar12",
		"Intern Search Results" : "eVar13",
		"Unified Source" : "eVar14",
		"Initial Unified Source" : "eVar15",
		"Invoice Typ" : "eVar16",
		"Advertising" : "eVar17",
		"Sale Type" : "eVar18",
		"Teaser ID" : "eVar19",
		"Initial Teaser ID" : "eVar20",
		"Target URL" : "eVar21",
		"Produkt Teaser" :  "eVar22",
		"Teaser ID Click" : "eVar23",
		"TV Teaser" : "eVar24",
		"TV Genre" : "eVar25",
		"Videothek Genre" : "eVar26",
		"Videothek Trailer" : "eVar27",
		"Order VPNr" : "eVar28",
		"Rechnugsweg" : "eVar29",
		"Zahlungsart" : "eVar30",
		"Webmail" : "eVar31",
		"FAQ versendet" : "eVar32",
		"PLZ Anfrage" : "eVar33",
		"SocialMediaMobile": "eVar34"
	};

	/**
	 * Hilfsmethode, um ULRS (und anderes) zu matchen und den zugewiesenen Wert zurueck zu geben
	 * @param ref Zu Ueberpruefender String
	 * @param msgs Array mit moeglichen Matches und dazugehoerenden Msgs
	 * @return die zu ref passende msg
	 */
	var _findMatch = function(ref, msgs)
	{
		for(var i=0; i < msgs.length; i++) {
		      if( ( ref == '' && msgs[i].url == null ) || ( ref > '' && ref.match( msgs[i].url ) ) ) {
		         return msgs[i].msg;
		      }
		}
		return null;
	};

	/**
	 * Tracking Account Daten anhand der URL auswaehlen (DEV oder LIVE)
	 */
	var _setTrackingAccount = function () {
		var url  = document.URL;
		var msgs = [
			{'url' : null, 'msg' : 'dev'},
			{'url' : /^http:\/\/?kabelbw-dev/, 'msg' : 'dev'},
			{'url' : /^http(s)?:\/\/romulus\.kabelbw\.de/, 'msg':'dev'},
			{'url' : /^http(s)?:\/\/remus\.kabelbw\.de/, 'msg':'dev'},
			{'url' : /^http(s)?:\/\/www\.kabelbw\.de/, 'msg':'live'},
			{'url' : /^http(s)?:\/\/webmail\.kabelbw\.de/, 'msg':'live'}
		];
		var systeme = ( _findMatch(url, msgs) == null ) ? 'dev' : _findMatch(url, msgs);
		var account = [];
		account["dev"] = config.trackingAccountDev;
		account["live"] = config.trackingAccount;

		return account[systeme];
	};

	/**
	* Entfernt alle Werte des Trackingobjekts um das Tracking alter Werte zu verhindern
	*/
	var _cleanObjekt = function(){
		var cleanProperty = function(propertySet){
			for(var prop in propertySet){
				window.s[propertySet[prop]] = null;
			}
		}
		cleanProperty(_events);
		cleanProperty(_trafficVars);
		cleanProperty(_eVars);
	}

	/**
	* Uebertraegt alle Tracking Propertys
	*/
	var _copyProperty = function(){
		for( var property in _trackingObject){
			window.s[property]  =_trackingObject[property];
		}
	}

	/**
	 * Gibt den den von Omniture generierten Tracking-Code aus
	 */
	var _writeCode = function(){
		window.s = s_gi( _setTrackingAccount() );// wird noch nicht verwendet
		_cleanObjekt();
		_copyProperty();
		return window.s.t();
	};

	/**
	 * Setzt (oder loescht) Parameter im Tracking Objekt
	 */
	var _setParams = function(params){
		for(param in params){
			_trackingObject[param] = params[param];
			if( params[param] === false ){
				delete _trackingObject[param];
			}
		}
		return _trackingObject;
	};
	/**
	 * Ermittelt das Event aus dem Mapping
	 */
	var _getEvent = function(event){
		return (_events[event]) ? _events[event] : event;
	};
	/**
	 * Ermittelt eine Var aus dem Mapping
	 */
	var _convertVars = function(input, mapping){
		var output = [];
		for(var value in input){
			output[mapping[value] || value] = input[value];
		}
		return output;
	};
	/**
	 * Ermittelt den Referer - wenn es weder vpid noch Suchmaschine ist, wird "organic" geantwortet
	 */
	var _getRefererData = function () {
		// zunaechst nach der vpid schauen. wenn vorhanden, ist das unser referer
		var hr = document.location.href;
		var start = hr.indexOf("vpid=");
		if(start > 0) {
			start = start + 5;
			var end = hr.indexOf("#", start);
			if(end <= 0) {
				end = hr.indexOf("&", start);
			}
			if(end > 0) {
				return hr.substring(start, end);
			} else {
				return hr.substring(start);
			}
		}

		// jetzt schauen wir mal nach suchmaschinen
		var ref  = document.referrer;
		var msgs = [
			{'url' : null, 'msg' : 'organic'},
			{'url' : /^http(s)?:\/\/(\w+\.)?google\.de/, 'msg':'google.de'},
			{'url' : /^http:\/\/(\w+\.)?google\.com/,    'msg':'google.com'},
			{'url' : /^http:\/\/(\w+\.)?yahoo\.de/,      'msg':'yahoo.de'},
			{'url' : /^http:\/\/(\w+\.)?yahoo\.com/,     'msg':'yahoo.com'},
			{'url' : /^http:\/\/(\w+\.)?bing\.de/,       'msg':'bing.de'},
			{'url' : /^http:\/\/(\w+\.)?bing\.com/,      'msg':'bing.com'},
			{'url' : /^http:\/\/(\w+\.)?web\.de/,        'msg':'web.de'},
			{'url' : /^http:\/\/(\w+\.)?lycos\.de/,      'msg':'lycos.de'}
		];
		var refererData = _findMatch(ref, msgs);
		if(refererData != null) return refererData;

		// wenn nix gefunden -> organic
		return "organic";
	};
	/**
	 * Setzt Variablen anhand anderer Variablen
	 */
	var _linkProperty = function(){

		var separator = ",";

		if( _trackingObject.channel && _trackingObject.prop1 && _trackingObject.pageName ){
			_setParams({
				"prop2" : _trackingObject.channel + separator + _trackingObject.prop1 + separator + _trackingObject.pageName
			});
		}
		if( _trackingObject.prop2 ){
			_setParams({
				"prop5" : _trackingObject.prop2
			});
		}
		if( _trackingObject.campaign ) {
			_setParams({
				"eVar6" : _trackingObject.campaign,
				"eVar10" : _trackingObject.campaign,
				"eVar14" : _trackingObject.campaign,
				"eVar15" : _trackingObject.campaign
			});
		} else if (_trackingObject.social) {
			_setParams({
				"eVar34" : _trackingObject.social
			});
		} else {
			_setParams({
				"eVar14" : _getRefererData(),
				"eVar15" : _getRefererData()
			});
		}
		if( _trackingObject.prop2 && _trackingObject.prop3 ) {
			_setParams({
				"prop4" : _trackingObject.prop2 + separator + _trackingObject.prop3
			});
		}
		if( _trackingObject.pageName ) {
			_setParams({
				"eVar7" : _trackingObject.pageName
			});
		}

		/*Vordefinierte Parameter suchen*/
		var parameter;
		if(parameter = _getTrackingParameter("redirect")){
			_setParams({"eVar21" : parameter});
		}
		if(parameter = _getTrackingParameter("teaserclick")){
			_setParams({"eVar22" : parameter });
		}

	};

	var _getTrackingParameter = function(param){
		var urlParams = document.location.href.split("?")[1];
		if(urlParams){
			var param = urlParams.split(param + "=")[1];
			if(param){
				param = param.split("&")[0];
				return param.split("#")[0];
			}else{
				return false;
			}
		}else{
			return false;
		}
	}

	/**
	 * Initialisiert das Traffic-Objekt mit Daten aus der Config
	 */
	var _init = function(){
		window.s_account = _setTrackingAccount();
		_setParams(
			_convertVars({
				"Report Suite" : _setTrackingAccount(),
				"Tracking Server" : config.trackingPort,
				"Visitor Name Space" : config.trackingVisitorNamespace
			},
			_trafficVars)
		);

	};

// ############################################################################ Ende Private Methoden/Properties

	// Objekt erstellen
	var _trackingObject = {}

	// initialisieren
	_init();

	// Public Methoden
	return {
		addParams : function(params){
			_setParams(params);
			return this;
		},
		clean : function () {
			_cleanObjekt();
			return this;
		},
		track : function(){
			_linkProperty();
			_writeCode();
			return this;
		},
		evars : function(evars){
			_setParams(_convertVars(evars, _eVars));
			return this;
		},
		traffic : function(trafficvars){
			_setParams(_convertVars(trafficvars, _trafficVars));
			return this;
		},
		event : function(event){
			_setParams({
				"events" : _getEvent(event)
			});
			return this;
		}
	};

});

