/* 
    jquery.serialize_json.js 
    ~~~~~~~~~~~~~~~~~~~~~~~~

    :copyright: (C) 2008 Florian Boesch <pyalot@gmail.com>
    :license: GNU AGPL3, see LICENSE for more details.
    :download: <http://hg.codeflow.org/tlog/archive/tip.tar.gz>
*/

(function($){
    reprString = function (o) {
        return ('"' + o.replace(/(["\\])/g, '\\$1') + '"'
            ).replace(/[\f]/g, "\\f"
            ).replace(/[\b]/g, "\\b"
            ).replace(/[\n]/g, "\\n"
            ).replace(/[\t]/g, "\\t"
            ).replace(/[\r]/g, "\\r");
    }

    $.serializeJson = function (o) {
        var objtype = typeof(o);
        if (objtype == 'number' || objtype == 'boolean') {
            return o.toString();
        }
        else if(objtype == 'string') {
            return reprString(o);
        }
        else if (o === null) {
            return 'null';
        }
        else if (objtype == "undefined") {
            return 'null';
        }
        else if(typeof(o.length) == "number") {
            var res = [];
            for (var i = 0; i < o.length; i++) {
                var val = $.serializeJson(o[i]);
                if (typeof(val) != "string") {
                    val = "undefined";
                }
                res.push(val);
            }
            return "[" + res.join(", ") + "]";
        }
        else{
            var res = [];
            for (var k in o) {
                var useKey;
                if (typeof(k) == "number") {
                    useKey = '"' + k + '"';
                } else if (typeof(k) == "string") {
                    useKey = reprString(k);
                } else {
                    // skip non-string or number keys
                    continue;
                }
                val = $.serializeJson(o[k]);
                if (typeof(val) != "string") {
                    // skip non-serializable values
                    continue;
                }
                res.push(useKey + ":" + val);
            }
            return "{" + res.join(", ") + "}";
        }
    }

    $.putJSON = function(path, data, options){
        var params = {
            beforeSend  : function(xhr){
                xhr.setRequestHeader('Content-Type', 'application/json');
                xhr.setRequestHeader('Accept', 'application/json');
            },
            url         : path,
            type        : 'PUT',
            data        : $.serializeJson(data)
        };
        if(typeof(options) == 'function'){
            params.success = options;
        }
        else if(options.success){
            params.success = options.success;
        }
        $.ajax(params);
    };

    $.postJSON = function(path, data, options){
        if(typeof(options) == 'function'){
            var success = options;
            var error = null;
        }
        else{
            var success = options.success;
            var error = options.error;
        }
        $.ajax({
            beforeSend  : function(xhr){
                xhr.setRequestHeader('Content-Type', 'application/json');
                xhr.setRequestHeader('Accept', 'application/json');
            },
            url         : path,
            type        : 'POST',
            data        : $.serializeJson(data),
            dataType    : 'json',
            success     : function(data){
                if(success){
                    success(data);
                }
            },
            error       : function(xhr, text, exception){
                if(xhr.status == 204 || xhr.status == 0){
                    if(success){
                       success();
                    }
                }
                else{
                    if(error){
                        error(text);
                    }
                }

            }
        });
    };
})(jQuery);
