/////////////////////////////////////////////////////
// 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();

	// We're now allowing regular places to exist alongside custom regions.
	// "p" and "place" will continue to be mutually exclusive, however.
	if(v) {
		if(k == "p") {
			this.remove('place');
		} else if(k == "place") {
			this.remove('p');
			this.remove('pLabel');
		}
	}
};

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('dlo');
	session2.remove('dloz');
	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('rp');
	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(params) {
	var urlParams
	if (!params)
		urlParams = getUrlParams();
	else
		urlParams = params;
	

	// Check privileges.  Periods filtered out in allowPeriods.js.jsp.  Overlay sets are checked in index_sites.jsp (NOT ANY MORE!!)
	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['dlo'] || urlParams['dloz'] || 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'] || urlParams['rp']) {
                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('dlo');
                this.remove('dloz');
                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');
                this.remove('rp');
        }

        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['mo']) {
		var mapOptions = urlParams['mo'];
		var mapOptionsArray = [];
		// Previously, the "mo" argument in map links was a comma-separated list. The
		// commas have been removed to make links cleaner looking, but we still need
		// to support the old links.
		if(mapOptions.indexOf(",") == -1) {
			// New link that does not contain commas. Add each option to the array.
			for(var i=0; i<mapOptions.length; i++) {
				mapOptionsArray.push(mapOptions.charAt(i));
			}
		} else {
			// Old link that contains commas. Split the string as we previously did.
			mapOptionsArray = urlParams['mo'].split(',');
		}
		
		// Store the map options in the session.
		this.put('mo', mapOptionsArray);
	}

        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['dlo']) this.put('dlo', urlParams['dlo']);
        if (urlParams['dloz']) this.put('dloz', urlParams['dloz']);
        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['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']);
        if (urlParams['rp']) this.put('rp', urlParams['rp']);
};

// returns if any map related objects are in session, e.g. indicators, places, pins
PSession2.prototype.getMapRelatedCount = function(val) {
	var retVal = 0;
	if(PEnvironment.pageName == 'analytics'){
		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') || this.get('dlo')) {
		var os = [];
		if(this.get('o')) {
			os = os.concat(this.get('o').split(","));
		}
		if(this.get('dlo')) {
			os = os.concat(this.get('dlo').split(","));
		}
		retVal = retVal + os.length;
	}
	
	// THIS IS ONLY TEMPORARY:
	//return retVal;
	return 0;
};

// 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;
};

