/*
	Journalize It Live Saver

	Built on top of prototype (http://prototype.conio.net/) and JSON (http://www.json.org/). Thanks.

	(c) 2006 Jan Lehnardt <jan@prima.de>
	
	Released under a BSD-style license. See the files footer for details; basically it's take it 
	and do what you like, but give proper credit.
*/


/* TODO:
	Enclose cookie controller into LiveSaver Object
	Register and restore entire forms. Prototype to the rescue!
*/

/*
	Cookie controller class to abstract away the handling of the LiveSaver cookie
*/
function LiveSaverCookieController()
{
	this.name = 'WP_LiveSaver';
	this.expires = new Date('January 17, 2038'); // do not expire until at least the 32bit UNIX epoch ends
	this.expires = this.expires.toGMTString();
	
	/*
		Constructs the cookie string and sets it to document.cookie
		
		param data data string
		
		return void
	*/
	this.save = function(data)
	{
		var value = this.name + '=' + escape(data) + '; ';
		var expires = 'expires=' + this.expires + ';';
		
		document.cookie = value + expires;
	}
	
	
	/*
		Return the value from the cookie
		
		return string
	*/
	this.load = function()
	{
		return this.getValue(this.name);
	}
	
	//Get cookie routine by Shelley Powers
	this.getValue = function(Name)
	{
		var search = Name + "="
		var returnvalue = "";
	
		if(document.cookie.length > 0) {
			offset = document.cookie.indexOf(search)
			// if cookie exists
			if(offset != -1) { 
				offset += search.length
				// set index of beginning of value
				end = document.cookie.indexOf(";", offset);
				// set index of end of cookie value
				if(end == -1) end = document.cookie.length;
				returnvalue = unescape(document.cookie.substring(offset, end))
			}
		}
		return returnvalue;
	}
}

var LiveSaver = new Object();

Object.extend(LiveSaver, {

	setId: function(id)
	{
		this.id = id;
	},
	
	setSaveThresold: function(saveThresold)
	{
		this.saveThresold = saveThresold;
	},
	
	
	
	init: function(id, data)
	{
		if(id) {
			this.id = id;
		} else if(this.wikiMedia && (this.wikiMedia == true)) {
			var wikiPage = window.location.href.match(/title=[^&]+&/);
			if(wikiPage) {
				this.id = window.location.hostname + window.location.pathname + wikiPage;
			} else {
				return false;
			}
			
		} else {
			this.id = window.location.href;
		}
		
		this.counter = {};
		this.saveThresold = 0;
		
		this.data = {};
		if(data) {
			this.data = data; // data!!
		}
		
		this.cookieController = new LiveSaverCookieController();
		// TODO: optmize. ask cookiecontroller if it has data. don't json everytime
		var tmpData = JSON.parse(this.cookieController.load());
		if(tmpData) {
			this.data = tmpData;
			
		
		/*	
			for(var fieldIdx in this.counter) {
				(fieldIdx);
				var count = this.counter[fieldIdx];
				if(this.data[this.id] && this.data[this.id][fieldIdx]) {
					var field = this.data[this.id][fieldIdx];
					if(field && field.length > 0) {
						this.counter[fieldIdx] = field.length
					}
				}
			}*/
		}
		
		if(!this.data[this.id]) {
			this.data[this.id] = {};
		}
	},
	
	enableWikiMedia: function()
	{
		this.wikiMedia = true;
	},
	
	// yo, I am static, no this available
	/*
	Dear Developer,
	if you're renaming the LiveSaver Object variable, you have to adjust the update function, too.
	Jan
	--
	*/
	update: function(element, value)
	{
		element = element.id;
		LiveSaver.counter[element]++;
		if(LiveSaver.counter[element] >= LiveSaver.saveThresold) {
			LiveSaver.counter[element] = 0;
			LiveSaver.add(element, value);
			LiveSaver.save();
		}
/*		LiveSaverCookieController.dump();*/
	},
	
	register: function(element)
	{
		this.counter[element] = -1;
		if(!this.data[this.id][element]) {
			this.data[this.id][element] = '';
		}
		if(this.has(element)) { //get saved data
			var value = this.get(element);
			element = $(element);
			if(element) {
				element.value = value;
			}			
		} else {
			if($(element).value.length > 0) { //get preset data
				this.add(element, $(element).value);
				this.save();
			}
		}
		new Form.Element.InputEventObserver(element, this.update);
	},

	save: function()
	{	
		var json = JSON.stringify(this.getAll());
		this.cookieController.save(json);
	},

	reset: function(element)
	{
		this.data.reset(element);
		this.save();
	},

	dump: function()
	{
		alert('dump:' + (this.cookieController.load()));
	},
	
	add: function(key, val)
	{
		this.data[this.id][key] = val;
	},

	get: function(key, doc)
	{
		if(this.has(key)) {
			return this.data[this.id][key];
		} else {
			return false;;
		}
	},

	has: function(key)
	{
		if(this.data[this.id] && this.data[this.id][key] && (this.data[this.id][key].length > 0)) {
			return true;
		} else {
			return false;
		}
	},

	getAll: function()
	{
		return this.data;
	},

	reset: function(key)
	{
		if(this.data[this.id][key]) {
			this.data[this.id][key] = null;
			this.save();
		}
	},
	
	
	hasData: function()
	{
		if(this.data[this.id]) {
			for(var fieldIdx in this.data[this.id]) {
				data = this.data[this.id][fieldIdx];
				if(data && data.length > 0) {
					return true;
				}
			}
		}
		return false;
	}
});


/*
* Copyright (c) 2006, Jan Lehnardt
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of LiveSaver nor the names of its contributors may 
*       be used to endorse or promote products derived from this software 
*       without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
