﻿//使用方法如下:
//设置cookie的名值对
//$.cookie(’name’, ‘value’);
//设置cookie的名值对，有效期，路径，域，安全
//$.cookie(’name’, ‘value’, {expires: 7, path: ‘/’, domain: ‘jquery.com’, secure: true});
//新建一个cookie 包括有效期 路径 域名等
//读取cookie的值
//var account= $.cookie(‘name’);
//删除一个cookie
//example $.cookie(’name’, null);

jQuery.cookie = function (key, value, options) {

    if (typeof value != 'undefined') { // name and value given, set cookie        
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        } else
            value = encodue(value);


        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expression_rs, otherwise they uate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [key, '=', value, expires, path, domain, secure].join('');

    } else {
        var cookies = {};
        var c = document.cookie + ";";

        var re = /\s?(.*?)=(.*?);/g;
        var matches;
        while ((matches = re.exec(c)) != null) {
            var name = matches[1];
            var value = matches[2];
            if (name == key) {
                return decodue(value);
            }
        }
        return null;
    }



    function encodue(v) {
        var enc;
        if (typeof v == "number") {
            enc = "n:" + v;
        } else if (typeof v == "boolean") {
            enc = "b:" + (v ? "1" : "0");
        } else if (v instanceof Date) {
            enc = "d:" + v.toGMTString();
        } else if (v instanceof Array) {
            var flat = "";
            for (var i = 0, len = v.length; i < len; i++) {
                flat += encodue(v[i]);
                if (i != len - 1)
                    flat += "^";
            }
            enc = "a:" + flat;
        } else if (typeof v == "object") {
            var flat = "";
            for (var key in v) {
                if (typeof v[key] != "function" && v[key] !== undefined) {
                    flat += key + "=" + encodue(v[key]) + "^";
                }
            }
            enc = "o:" + flat.substring(0, flat.length - 1);
        } else {
            enc = "s:" + v;
        }
        return escape(enc);

    }

    function decodue(cookie) {
        var re = /^(a|n|d|b|s|o)\:(.*)$/;
        var matches = re.exec(unescape(cookie));
        if (!matches || !matches[1])
            return; // non state cookie
        var type = matches[1];
        var v = matches[2];
        switch (type) {
            case "n":
                return parseFloat(v);
            case "d":
                return new Date(Date.parse(v));
            case "b":
                return (v == "1");
            case "a":
                var all = [];
                var values = v.split("^");
                for (var i = 0, len = values.length; i < len; i++) {
                    all.push(decodue(values[i]));
                }
                return all;
            case "o":
                var all = {};
                var values = v.split("^");
                for (var i = 0, len = values.length; i < len; i++) {
                    var kv = values[i].split("=");
                    all[kv[0]] = decodue(kv[1]);
                }
                return all;
            default:
                return v;
        }
    }

}


jQuery.fn.decookie = function () {
    var tag = $(this).attr("tagName");
    switch (tag) {
        case 'FORM':
            $(this).decookieForm();
            break;
        case 'UL':
            $(this).decookieOrder();
            break;
        default:
            alert('不支持此DOM的cookie操作');
            break;
    }

}


jQuery.fn.cookie = function () {
    var tag = $(this).attr("tagName");
    switch (tag) {
        case 'FORM':
            $(this).cookieForm();
            break;
        case 'UL':
            $(this).cookieOrder();
            break;
        default:
            alert('不支持此DOM的cookie操作');
            break;
    }
}



jQuery.fn.decookieForm = function () {
    if ($(this).attr("tagName") != 'FORM') {
        alert('此方法只支持form的cookie操作');
        return;
    }


    var object

    var formName = $(this).attr("name");


    cookies = jQuery.cookie(formName);


    if (!cookies || cookies.length <= 0)
        return;

    $('input, textarea, select,', this).each(function () {
        var elementID = this.id;

        var type = this.type;

        disabled = this.disabled;

        val = cookies[elementID] || "";

        if (!disabled) {
            switch (type) {
                case 'textarea':
                case 'text':
                    this.value = val;
                    break;
                case 'select-one':
                case 'select-multiple':
                    $(this).select(val);
                    break;
                case 'radio':
                case 'checkbox':
                    this.checked = !!val;
                    break;
                default:
                    break;
            }
        }
    });


}



jQuery.fn.cookieForm = function () {
    if ($(this).attr("tagName") != 'FORM') {
        alert('此方法只支持form的cookie操作');
        return;
    }

    var formName = $(this).attr("name");
    var formObj = {};
    $('input, textarea, select,', this).each(function () {
        var type = this.type;

        if (this.tagName == 'INPUT' && type != 'text' && type != 'radio' && type != 'checkbox') {
            return;
        }

        var value = this.value;

        if (type == 'select-multiple') {
            value = $(this).select();
        }

        var elementID = this.id;

        if (!elementID) {
            alert("this element didn't have ID, could not be cookied,name:"
     + name);
            return;
        }

        if ((type == 'radio' || type == 'checkbox') && !this.checked) {
            value = '';
        }

        formObj[this.id] = value;
    });

    jQuery.cookie(formName, formObj);


}



jQuery.fn.select = function (values) {

    if (!values) {
        values = [];
        jQuery('option:selected', this).each(function () {
            values.push(this.value);
        });

        return values;
    }

    if (!(values instanceof Array)) {
        values = [values];
    }

    jQuery('option', this).each(function () {
        this.selected = false;

        if (jQuery.inArray(this.value, values) >= 0) {
            this.selected = true;
        }
    });
}





jQuery.fn.cookieOrder = function () {
    // save custom order to cookie
    var key = $(this).attr("id");
    $.cookie(key, $(this).sortable("toArray"));
}


jQuery.fn.decookieOrder = function () {
    var list = $(this);
    if (list == null) return

    // fetch the cookie value (saved order)
    var key = $(this).attr("id");

    var IDs = $.cookie(key);

    if (!IDs) return;
    //IDs = IDs.split(",");

    // fetch current order
    var items = list.sortable("toArray");

    // make array from current order
    var rebuild = new Array();
    for (var v = 0, len = items.length; v < len; v++) {
        rebuild[items[v]] = items[v];
    }

    for (var i = 0, n = IDs.length; i < n; i++) {

        // item id from saved order
        var itemID = IDs[i];

        if (itemID in rebuild) {

            // select item id from current order
            var item = rebuild[itemID];

            // select the item according to current order
            var child = $("ul.ui-sortable").children("#" + item);

            // select the item according to the saved order
            var savedOrd = $("ul.ui-sortable").children("#" + itemID);

            // remove all the items
            child.remove();

            // add the items in turn according to saved order
            // we need to filter here since the "ui-sortable"
            // class is applied to all ul elements and we
            // only want the very first! You can modify this
            // to support multiple lists - not tested!
            $("ul.ui-sortable").filter(":first").append(savedOrd);
        }
    }
}

