/*
	Copyright (c) 2004-2006, The Dojo Foundation
	All Rights Reserved.

	Licensed under the Academic Free License version 2.1 or above OR the
	modified BSD license. For more information on Dojo licensing, see:

		http://dojotoolkit.org/community/licensing.shtml
*/

dojo.provide("dojo.widget.html.stabile");

dojo.widget.html.stabile = {
	// summary: Maintain state of widgets when user hits back/forward button

	// Characters to quote in single-quoted regexprs
	_sqQuotables: new RegExp("([\\\\'])", "g"),

	// Current depth.
	_depth: 0,

	// Set to true when calling v.toString, to sniff for infinite
	// recursion.
	_recur: false,

	// Levels of nesting of Array and object displays.
	// If when >= depth, no display or array or object internals.
	depthLimit: 2
};

//// PUBLIC METHODS

dojo.widget.html.stabile.getState = function(id){
	// summary
	//	Get the state stored for the widget with the given ID, or undefined
	//	if none.

	dojo.widget.html.stabile.setup();
	return dojo.widget.html.stabile.widgetState[id];
}

dojo.widget.html.stabile.setState = function(id, state, isCommit){
	// summary
	//		Set the state stored for the widget with the given ID.  If isCommit
	//		is true, commits all widget state to more stable storage.

	dojo.widget.html.stabile.setup();
	dojo.widget.html.stabile.widgetState[id] = state;
	if(isCommit){
		dojo.widget.html.stabile.commit(dojo.widget.html.stabile.widgetState);
	}
}

dojo.widget.html.stabile.setup = function(){
	// summary
	//		Sets up widgetState: a hash keyed by widgetId, maps to an object
	//		or array writable with "describe".  If there is data in the widget
	//		storage area, use it, otherwise initialize an empty object.

	if(!dojo.widget.html.stabile.widgetState){
		var text = dojo.widget.html.stabile._getStorage().value;
		dojo.widget.html.stabile.widgetState = text ? dj_eval("("+text+")") : {};
	}
}

dojo.widget.html.stabile.commit = function(state){
	// summary
	//		Commits all widget state to more stable storage, so if the user
	//		navigates away and returns, it can be restored.

	dojo.widget.html.stabile._getStorage().value = dojo.widget.html.stabile.description(state);
}

dojo.widget.html.stabile.description = function(v, showAll){
	// summary
	//		Return a JSON "description string" for the given value.
	//		Supports only core JavaScript types with literals, plus Date,
	//		and cyclic structures are unsupported.
	//		showAll defaults to false -- if true, this becomes a simple symbolic
	//		object dumper, but you cannot "eval" the output.

	// Save and later restore dojo.widget.html.stabile._depth;
	var depth = dojo.widget.html.stabile._depth;

	var describeThis = function() {
		 return this.description(this, true);
	}

	try {

		if(v===void(0)){
			return "undefined";
		}
		if(v===null){
			return "null";
		}
		if(typeof(v)=="boolean" || typeof(v)=="number"
		    || v instanceof Boolean || v instanceof Number){
			return v.toString();
		}

		if(typeof(v)=="string" || v instanceof String){
			// Quote strings and their contents as required.
			// Replacing by $& fails in IE 5.0
			var v1 = v.replace(dojo.widget.html.stabile._sqQuotables, "\\$1");
			v1 = v1.replace(/\n/g, "\\n");
			v1 = v1.replace(/\r/g, "\\r");
			// Any other important special cases?
			return "'"+v1+"'";
		}

		if(v instanceof Date){
			// Create a data constructor.
			return "new Date("+d.getFullYear+","+d.getMonth()+","+d.getDate()+")";
		}

		var d;
		if(v instanceof Array || v.push){
			// "push" test needed for KHTML/Safari, don't know why -cp

			if(depth>=dojo.widget.html.stabile.depthLimit)
			  return "[ ... ]";

			d = "[";
			var first = true;
			dojo.widget.html.stabile._depth++;
			for(var i=0; i<v.length; i++){
				// Skip functions and undefined values
				// if(v[i]==undef || typeof(v[i])=="function")
				//   continue;
				if(first){
					first = false;
				}else{
					d += ",";
				}
				d+=arguments.callee(v[i], showAll);
			}
			return d+"]";
		}

		if(v.constructor==Object
		    || v.toString==describeThis){
			if(depth>=dojo.widget.html.stabile.depthLimit)
			  return "{ ... }";

			// Instanceof Hash is good, or if we just use Objects,
			// we can say v.constructor==Object.
			// IE (5?) lacks hasOwnProperty, but perhaps objects do not always
			// have prototypes??
			if(typeof(v.hasOwnProperty)!="function" && v.prototype){
				throw new Error("description: "+v+" not supported by script engine");
			}
			var first = true;
			d = "{";
			dojo.widget.html.stabile._depth++;
			for(var key in v){
				// Skip values that are functions or undefined.
				if(v[key]==void(0) || typeof(v[key])=="function")
					continue;
				if(first){
					first = false;
				}else{
					d += ", ";
				}
				var kd = key;
				// If the key is not a legal identifier, use its description.
				// For strings this will quote the stirng.
				if(!kd.match(/^[a-zA-Z_][a-zA-Z0-9_]*$/)){
					kd = arguments.callee(key, showAll);
				}
				d += kd+": "+arguments.callee(v[key], showAll);
			}
			return d+"}";
		}

		if(showAll){
			if(dojo.widget.html.stabile._recur){
				// Save the original definitions of toString;
				var objectToString = Object.prototype.toString;
				return objectToString.apply(v, []);
			}else{
				dojo.widget.html.stabile._recur = true;
				return v.toString();
			}
		}else{
			// log("Description? "+v.toString()+", "+typeof(v));
			throw new Error("Unknown type: "+v);
			return "'unknown'";
		}

	} finally {
		// Always restore the global current depth.
		dojo.widget.html.stabile._depth = depth;
	}

}



//// PRIVATE TO MODULE

dojo.widget.html.stabile._getStorage = function(){
	// summary
	//	Gets an object (form field) with a read/write "value" property.

	if (dojo.widget.html.stabile.dataField) {
		return dojo.widget.html.stabile.dataField;
	}
	var form = document.forms._dojo_form;
	return dojo.widget.html.stabile.dataField = form ? form.stabile : {value: ""};
}

