/**
 * Autosave jQuery plugin
 *
 * Copyright (c) 2008 Rik Lomas (rikrikrik.com)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */
;(function($) {

	$.fn.autosave = function(options) {
		var ev = false,
			doSave = false,
			ti = 0,
			ci = 0,
			ri = 0,		
			values = {
				'text': {},
				'check': {},
				'radio': {}
			};
	
		var settings = {
			autosave: '.autosave',
			restore: '.autosave_restore',
			removeCookies: '.autosave_removecookies',
			saving: '.autosave_saving',
			interval: 10000,
			unique: '',
			onBeforeSave: function () { },
			onAfterSave: function () { },
			onBeforeRestore: function () { },
			onAfterRestore: function () { },
			cookieCharMaxSize: 2000,
			cookieExpiryLength: .04,
			autorestore: true
		};
		
		if (options) {
			$.extend(settings, options);
		}
	
		var go = function () {
			settings.onBeforeSave();
			
			var m = values,
				u = settings.unique,
				i = 0;
			
			var saveCookie = function(i, j, content) {
				$.cookie('autosave_' + u + i + '_' + j, content, {expires: settings.cookieExpiryLength});
			}
		
			var removeBiggerCookies = function(i) {
				var j = 1;
				while ($.cookie('autosave_' + u + i + '_' + j) !== null && j < 20) {
					$.cookie('autosave_' + u + i + '_' + j, null);
				}
			}
				
			for (i in m.text) {
				var content,
					j = 0,
					content = $(m.text[i]).val(),
					size = content.length;
			
				if (size < settings.cookieCharMaxSize) {
					saveCookie(i, 0, content);
				} else {
					removeBiggerCookies(i);
					for (var k = 0; k < size; k += settings.cookieCharMaxSize) {
						saveCookie(i, j, content.substr(k, settings.cookieCharMaxSize));
						j += 1;
					}
				}
			}
		
			var cookiecheck = '';
			for (i in m.check) {
				var content = $(m.check[i]).attr('checked') ? '1' : '0';
				cookiecheck += content + ',';
			}
			$.cookie('autosave_' + u + '_check', cookiecheck, {expires: settings.cookieExpiryLength});
		
			var cookieradio = '';
			for (i in m.radio) {
				if($(m.radio[i]).is(':checked')) {
					cookieradio += i + ',';
				}
			}
			$.cookie('autosave_' + u + '_radio', cookieradio, {expires: settings.cookieExpiryLength});
		
			saving();
			
			settings.onAfterSave();
		};
	
		var restore = function() {
			settings.onBeforeRestore();
			
			var m = values,
				u = settings.unique,
				i = 0;
		
			for (i in m.text)
			{
				var j = 0,
					restored = '';
				while ($.cookie('autosave_' + u + i + '_' + j) !== null && j < 20) {
					restored += $.cookie('autosave_' + u + i + '_' + j);
					j += 1;
				}
				$(m.text[i]).val(restored);
			}
		
			var cookiecheck = ($.cookie('autosave_' + u + '_check') || '').split(',');
			if (cookiecheck !== null) {
				cookiecheck.pop(); // Get rid of last element
				for (i in m.check) {
					var chek = (cookiecheck[i] == '1') ? 'checked' : '';
					$(m.check[i]).attr('checked', chek);
				}
			}
				
			var cookieradio = ($.cookie('autosave_' + u + '_radio') || '').split(',');
			if (cookieradio !== null) {
				cookieradio.pop(); // Get rid of last element
				for (i in cookieradio) {
					$(m.radio[cookieradio[i]]).attr('checked', 'checked');
				}
			}
					
			settings.onAfterRestore();
		};
	
		var removeAllCookies = function() {
			var u = settings.unique,
				i, j;
		
			for (i = 0; i < 200; i++) {
				j = 0;
				while ($.cookie('autosave_' + u + i + '_' + j) !== null && j < 20) {
					$.cookie('autosave_' + u + i + '_' + j, null);
				}
			}
		
			$.cookie('autosave_' + u + '_check', null);
			$.cookie('autosave_' + u + '_radio', null);
		};
	
		var saving = function() {
			$(settings.saving).show().fadeTo(1000, 1).fadeOut(500);
		};		
          
        var setEvents = function() {
			$(settings.saving).hide();
                
			$(settings.autosave).click(function() {
				go();
				return false;
			});
			
			$(settings.restore).click(function() {
				restore();
				return false;
			});
			
			$(settings.removeCookies).click(function() {
				removeAllCookies();
				return false;
			});
        
            var onUnload = function() {
				go();
				return true;
			};
                
            if($.browser.msie) {
                window.attachEvent('onbeforeunload', onUnload);
            } else {
                $(window).unload(onUnload);
            }
            
			setInterval(function () {
                if (doSave) {
					go();
					doSave = false;
				} 
			}, settings.interval);
			ev = true;
		}
            
		var result = this.filter(':text, :radio, :checkbox, select, textarea').each(function () {
			if ($(this).is(':text, textarea')) {
				values.text[ti] = this;
				$(this).keyup(function() {
					doSave = true;
				});
				ti++;
			} else if ($(this).is('select')) {
				values.text[ti] = this;
				$(this).change(function() {
					doSave = true;
				});
				ti++;
			} else if ($(this).is(':checkbox')) {
				values.check[ci] = this;
				$(this).click(function() {
					doSave = true;
				});
				ci++;
			} else {
				values.radio[ri] = this;
				$(this).click(function() {
					doSave = true;
				});
				ri++;
			}
                
			if (!ev) { setEvents(); }
		});

		if (settings.autorestore){
			restore();
		}
            
        return result;
	};
	
})(jQuery);

