var _smec = {};

// smec cookie functions
_smec.cookies = function () {
    var getCookie = function(name) {
		var start = document.cookie.indexOf( name + "=" );
		var len = start + name.length + 1;
		if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
			return null;
		}
		if ( start == -1 ) {return null;}
		var end = document.cookie.indexOf( ';', len );
		if ( end == -1 ) {end = document.cookie.length;}
		return unescape( document.cookie.substring( len, end ) );
	};
	var setCookie = function ( name, value, expires, path, domain, secure ) {
		var today = new Date();
		today.setTime( today.getTime() );
		if ( expires ) {
			expires = expires * 1000 * 60 * 60 * 24;
		}
		var expires_date = new Date( today.getTime() + (expires) );
		document.cookie = name+'='+escape( value ) +
			( ( expires ) ? ';expires='+expires_date.toGMTString() : '' ) + //expires.toGMTString()
			( ( path ) ? ';path=' + path : '' ) +
			( ( domain ) ? ';domain=' + domain : '' ) +
			( ( secure ) ? ';secure' : '' );
	};
	var deleteCookie = function ( name, path, domain ) {
		if ( getCookie( name ) ) {
			document.cookie = name + '=' +
				( ( path ) ? ';path=' + path : '') +
				( ( domain ) ? ';domain=' + domain : '' ) +
				';expires=Thu, 01-Jan-1970 00:00:01 GMT';
		}
	};
	return {
		getCookie: getCookie,
		setCookie: setCookie,
		deleteCookie: deleteCookie
	};
}();

// smec misc functions
_smec.misc = function() {
	var getRandomArbitary = function (min, max) {
		return Math.floor(Math.random() * (max - min) + min);
	};
	var pseudoUUID = function() {
		return "" + (new Date).getTime() + "-" + getRandomArbitary(100000,900000);
	};
	var zeroPad = function(num, count) {
		var numZeropad = num + '';
		while(numZeropad.length < count) {
			numZeropad = "0" + numZeropad;
		}
		return numZeropad;
	};
	return {
		pseudoUUID: pseudoUUID,
		zeroPad: zeroPad
	};
}();
 


// smec attribution functions, requires _smec.cookie
_smec.attribution = function() {
	var VERSION = "v0_9";
	var COOKIE_NAME = "__smecattr" + VERSION;
	var COOKIE_EXPIRES_IN_DAYS = 60;
	var MAX_EVENT_LEN=5;
	
	// patterns
	var patterns = {
		'Google-Adwords' : ['loc', new RegExp('[&?]gclid='), new RegExp('[&?]q=([^&]*)'), 1],	
		'Google-Search' :  ['ref', new RegExp('^https?://(www\.)?google\.'), new RegExp('[&?]q=([^&]*)'), 1]
	};

	
	// objects
	var head = function(visitorId) {
		this.visitorId = visitorId;
		this.serialize = function() {
			return this.visitorId;
		};
		this.deserialize = function(serialized) {
			this.visitorId = serialized;
			return this;
		};
	};
	var event = function(source, context) {
		this.source = source;
		this.context = context;
		this.timestamp = 'TODO';
		this.serialize = function() {
			var now = new Date();
			var timestamp = _smec.misc.zeroPad(now.getUTCFullYear()-2000) + "" 
				+ _smec.misc.zeroPad(now.getUTCMonth() + 1, 2) + "" + _smec.misc.zeroPad(now.getUTCDate(), 2)
				+ ':'
				+ _smec.misc.zeroPad(now.getUTCHours(), 2) + _smec.misc.zeroPad(now.getUTCMinutes(), 2)
			return timestamp + "," + source + "," + context;
		};
		this.deserialize = function(serialized) {
			this.visitorId = serialized;
			var splitted = serialized.split(/,/);
			this.timestamp = splitted[0];
			this.source = splitted[1];
			this.context = splitted[2];
			return this;
		};
	};
	var state = function(head, events) {
		this.head = head ? head : new _smec.attribution.head(_smec.misc.pseudoUUID());
		this.events = events  ? events : [];
		this.serialize = function() {
			var serialized =  this.head.serialize();
			for (var i = 0; i < this.events.length; i++) {
				serialized +=  '/' + this.events[i].serialize();
			}
			return serialized;
		};
		this.deserialize = function(serialized) {
			var splitted = serialized.split('[/]');
			this.head = (new _smec.attribution.head()).deserialize((splitted[0]));
			this.events = [];
			for (var i=1; i < splitted.length; i++) {
				var event = new _smec.attribution.event();
				event.deserialize((splitted[i]));
				this.events.push(event);
			}
			return this;
		};
	};
	

	var classifyVisit = function(state) {	
		for (var source in patterns) {
			var matchTargetType = patterns[source][0];
			var matchTarget = matchTargetType == 'loc' ? location.href : document.referrer;
			var sourceMatcher = patterns[source][1];
			if (matchTarget.match(sourceMatcher)) {
				var termMatcher = patterns[source][2];
				var termGroup = patterns[source][3];
				var referrer = document.referrer ? document.referrer : '';
				var terms = referrer.match(termMatcher)[termGroup];
				var event = new _smec.attribution.event(source, terms);
				state.events.push(event);
				break;
			}
		}
	};
	var track = function() {
		var cookieValue = _smec.cookies.getCookie(COOKIE_NAME);		
		var state = cookieValue ? (new _smec.attribution.state()).deserialize(cookieValue) : new _smec.attribution.state();		
		
		//TODO: cut long histories
		//TODO: cut double entries
		
		classifyVisit(state);
	
		cookieValue = state.serialize();
		_smec.cookies.setCookie(COOKIE_NAME, cookieValue, COOKIE_EXPIRES_IN_DAYS); 
		return cookieValue;
	};	
	
	return {		
		// private for beta version, exposed for test purposes (TODO: remove this)
		event: event,
		head: head,
		state: state,
		
		// public
		track: track
	};	
}();




