/**
 * 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: 1000,
                        unique: '',
                        onBeforeSave: function () { },
                        onAfterSave: function () { },
                        onBeforeRestore: function () { },
                        onAfterRestore: function () { },
                        cookieCharMaxSize: 2000,
                        cookieExpiryLength: 1,
                        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);
