/////////////////////////////////////////////////////
// PSession2                                       //
/////////////////////////////////////////////////////
PSession2 = function(data) {
	this.dirty = false;
	this.eventManager = new PEventManager();
	this.data = {};
	if (data)
		this.init(data);
	this.url = "rest/session";
}
PSession2.prototype.init = function(data) {
	var v;
	for (var k in data) {
		v = data[k];
		this.put(k, v && v != '' ? MochiKit.Base.evalJSON(v) : '');
	}
}
PSession2.prototype.onput = function(k, v) { 
	this.eventManager.triggerListeners('put', k, v); 
}
PSession2.prototype.onremove = function(k) { 
	this.eventManager.triggerListeners('remove', k); 
}
PSession2.prototype.onchange = function() { 
	this.eventManager.triggerListeners('change'); 
}
PSession2.prototype.addListener = function(eventId, f) {
	this.eventManager.addListener(eventId, f);
}
PSession2.prototype.fromHistory = function(id, d) {
	if (id) {
		this.fromRaw(d);
		if (d && this.onchange) this.onchange();
	}
}
PSession2.prototype.toMomentoId = function() {
	return Math.random() * 1000 % 10;
	var ret = '';
	var arr = [];

	var places = this.get('places');
	if (places) {
		var l = places.length;
		for (var i=0; i<l; i++) {
			arr.push(places[i].id);
		}
	}

	ret += arr.length==0 ? '' : 'p=' + arr.join(',');
	return ret;
}
PSession2.prototype.get = function(k) {
	return this.data[k];
}
PSession2.prototype.put = function(k, v) {
	// KLUGE: convert to string (so we don't have problems running functions like split() on values + handle null
	// Only do this on numeric types, so we can serialize arrays and objects -- John
	if (typeof v == "number") v += "";
	this.data[k] = v;
	this.dirty = true;
	this.onput(k, v);
	this.onchange();

	// only allow for one type of location saved to session at one time
	// 'chp' is for storing multiple places for tables and is excluded from this,
	// as tables can have multiple places alongside a custom region and polygon.
	if (v) {
		if (k == "p") {
			this.remove('place');
			this.remove('cp');
		} else if (k == "place") {
			this.remove('p');
			this.remove('pLabel');
			this.remove('cp');
		} else if (k == "cp") {
			this.remove('p');
			this.remove('pLabel');
			this.remove('place');
		}
	}
}
PSession2.prototype.remove = function(k) {
	this.data[k] = undefined;
	// delete not working
	//delete this.data[k];
	this.onremove();
}
PSession2.prototype.removeAllRelevant = function() {
	// remove relevant session vars
	session2.remove('i');
	session2.remove('btd');
	session2.remove('p');
	session2.remove('chp');
	session2.remove('pLabel');
	session2.remove('o');
	session2.remove('period');
	session2.remove('place');
	session2.remove('lat');
	session2.remove('lng');
	session2.remove('zoom');
	//session2.remove('prevmaps');
	session2.remove('ofilters');
	session2.remove('cp');
	session2.remove('nb');
	session2.remove('mo');
	session2.remove('legendind');
	session2.remove('mvalayers');
	session2.remove('lind');
	session2.remove('bid');
	session2.remove('pname');
	session2.remove('plat');
	session2.remove('plng');
	session2.remove('agg');
	session2.remove('ps');
	session2.remove('m0i');
	session2.remove('m1i');
	session2.remove('m2i');
}

PSession2.prototype.fromRaw = function(o) {
	for (var k in o)
		this[k] = o[k];
}
PSession2.prototype.historicize = function() {
	dhtmlHistory.add(this.toMomentoId(), this);
}
PSession2.prototype.toHTTP = function(prefix, encoder) {
	var all = [];
	var d = this.data;
	for (var k in d) {
		var v = d[k];
		var json = (v ? MochiKit.Base.serializeJSON(v) : '');
//		if (k == "prevmaps") {
//			alert('got json: ' + json + ', from prevmaps: ' + v);
//		}
		all.push(k + '=' + (encoder ? encoder(json) : encodeURIComponent(json)));
	}
	return (prefix ? prefix : '') + all.join('&');
}

// Saves the session in the server.
PSession2.prototype.save = function() {
	if (this.dirty == false) return;

	//var url = this.url + '/set/' + new Date().getTime() + Math.random() + this.toURI('', null);
	var url = this.url + '/set/' + new Date().getTime() + Math.random(); 
	var that = this;
	var requestobj = PXmlHttp.create();
	if (requestobj) {
		var params = this.toHTTP('', null);
		requestobj.open('POST', url, false);
		requestobj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		requestobj.setRequestHeader("Content-length", params.length);
		requestobj.setRequestHeader("Connection", "close");
		requestobj.send(params);
	}
}

PSession2.prototype.load = function() {
	PAsync2.call(this.url + '/debug', function(o) { this.data = o; });
}

// check url for params and save to session accordingly
PSession2.prototype.checkUrl = function() {

	var urlParams = PWebUtil.parseQuery(window.location.search);

	// Check privileges.  Periods filtered out in allowPeriods.js.jsp.  Overlay sets are checked in index_sites.jsp
	if (urlParams['o']) {
		var os = urlParams['o'].split(",");
		for (var i=0; i<os.length; i++) {
			if( !allowedPinsets[ os[i] ] )
				return;
		}
	}

	// show alert for maps that were saved with stale indicators
	var staleIndicators = function(id, analytics) {
		// these indicators are no longer available
		var staleInds = [9609197,9608806,9608894,9608769,9608989,9608896];
		for (var i=0; i<staleInds.length; i++) {
			if (staleInds[i] == id) {
				var alerter = new PAlerter2();
				var text = "The data layer that was saved with this page is no longer available. Please use the Add Data Layer menu above to select an alternative indicator.";
				// different more descriptive copy for analytics page
				if (analytics)
					var text = "One or more of the data layers saved with this page is no longer available. Please use the Add Data Layer menu above to select an alternative indicator.";
				alerter.popup(text, null, null, "OK");
				return true;
			}
		}
		return false;
	};

        if( urlParams['i'] && !ria[urlParams['i']]) { // indicator
		if (staleIndicators(urlParams['i']));
	                return;
        }

        // check if any of the params we're looking for exists in the url, if so remove params
        if (urlParams['i'] || urlParams['btd'] || urlParams['p'] || urlParams['chp'] || urlParams['period'] || urlParams['place'] || urlParams['o'] || urlParams['ofilters'] || urlParams['cp'] || urlParams['nb'] || urlParams['mo'] || urlParams['lng'] || urlParams['lat'] || urlParams['zoom'] || urlParams['iwx'] || urlParams['iwy'] || urlParams['lind'] || urlParams['bid'] || urlParams['pname'] || urlParams['plat'] || urlParams['plng'] || urlParams['agg']) {
                this.remove('i');
                this.remove('btd');
                this.remove('p');
                this.remove('chp');
                this.remove('pLabel');
                this.remove('period');
                this.remove('place');
                this.remove('o');
                this.remove('ofilters');
                this.remove('cp');
                this.remove('nb');
                this.remove('mo');
                this.remove('lng');
                this.remove('lat');
                this.remove('zoom');
                this.remove('lind');
                this.remove('bid');
                this.remove('pname');
                this.remove('plat');
                this.remove('plng');
                this.remove('agg');
        }

        if (urlParams['m0i'] || urlParams['m1i'] || urlParams['m2i']) {
        	for(var i=0; i<3; i++){
        		this.remove("m"+i+"i");
        		this.remove("m"+i+"btd");
        		this.remove("m"+i+"r0");
        		this.remove("m"+i+"r1");
        		this.remove("m"+i+"period");
        		this.remove("m"+i+"v");

			// show alert for stale indicators in analytics
        		if(urlParams["m"+i+"i"] && !ria[urlParams["m"+i+"i"]]) {
				if (staleIndicators(urlParams["m"+i+"i"], true)) {
					continue;
				}
			}
			if(urlParams["m"+i+"i"]) this.put("m"+i+"i", urlParams["m"+i+"i"]);
        		if(urlParams["m"+i+"btd"]) this.put("m"+i+"btd", urlParams["m"+i+"btd"]);
        		if(urlParams["m"+i+"r0"]) this.put("m"+i+"r0", urlParams["m"+i+"r0"]);
        		if(urlParams["m"+i+"r1"]) this.put("m"+i+"r1", urlParams["m"+i+"r1"]);
        		if(urlParams["m"+i+"period"]) this.put("m"+i+"period", urlParams["m"+i+"period"]);
        		if(urlParams["m"+i+"v"]) this.put("m"+i+"v", urlParams["m"+i+"v"]);
        	}
        }

        
        if (urlParams['i']) this.put('i', urlParams['i']);
        if (urlParams['btd']) this.put('btd', urlParams['btd']); 
        if (urlParams['p']) this.put('p', urlParams['p']);
        if (urlParams['chp']) this.put('chp', urlParams['chp']);
        if (urlParams['period']) this.put('period', urlParams['period']);
        if (urlParams['place']) this.put('place', unescape(urlParams['place']));
        if (urlParams['o']) this.put('o', urlParams['o']);
        if (urlParams['ofilters']) this.put('ofilters', PFilterUtil.getFilterMap(urlParams['ofilters']));
        if (urlParams['cp']) this.put('cp', urlParams['cp']);
        if (urlParams['nb']) this.put('nb', urlParams['nb']);
        if (urlParams['mo']) this.put('mo', urlParams['mo'].split(','));
        if (urlParams['rmp']) this.put('rmp', urlParams['rmp']);
        if (urlParams['lind']) this.put('lind', urlParams['lind']);
        if (urlParams['bid']) this.put('bid', urlParams['bid']);
        if (urlParams['pname']) this.put('pname', urlParams['pname']);
        if (urlParams['plat']) this.put('plat', urlParams['plat']);
        if (urlParams['plng']) this.put('plng', urlParams['plng']);
        if (urlParams['agg']) this.put('agg', urlParams['agg']);
}

// returns if any map related objects are in session, e.g. indicators, places, pins
PSession2.prototype.getMapRelatedCount = function(val) {
	var retVal = 0;
	if(typeof PAGE_ID != 'undefined' && PAGE_ID == "a_"){
		if(this.get('m0i')) retVal++;
		if(this.get('m1i')) retVal++;
		if(this.get('m2i')) retVal++;
	}else if (this.get('i')) 
		retVal++;
	// only allow one type of location
	if (this.get('p')) 
		retVal++;
	else if (this.get('place')) 
		retVal++;
	else if (this.get('cp')) 
		retVal++;
	// special case for overlays (get all)
	if (this.get('o')) {
		var os = this.get('o').split(",");
		retVal = retVal + os.length;
	}
	
	return retVal;
}

// get formated filters from session
PSession2.prototype.getFilters = function(id,ignorecolorcode) {
	var jFilters = [];
	if (this.get('ofilters'))
		jFilters = this.get('ofilters');
	
	if (jFilters[id]) {
		var filters = [];
		for (var j in jFilters[id]) {
			var jFilters2 = jFilters[id][j];
			var l = jFilters2.length;
			for (var k=0; k<l; k++) {
				var jFilter = jFilters2[k];
				// hack for ignoring color coding on charts
				if (!(jFilter.values == "COLORCODE" && ignorecolorcode)) {
					var filter = new PAttributeFilter(jFilter.name,jFilter.values,jFilter.type,jFilter.valuesDisplay,jFilter.columnName,jFilter.columnType);
					filters.push(filter);
				}
			}
		}
		return filters;
	} else
		return false;
}
