// Core
jQuery.ja =
{
    _ajaxRunning: true,
    _ajaxQueue: new Array(),
    _ajaxQueueProc: null,

    ajax: function(url, data, callback, noQueue)
    {
        var thisObj = this;

        if (noQueue)
        {
            jQuery.ajax(
            {
                url: url,
                data: (data ? data : {}),
                type: "POST",
                dataType: "json",
                cache: false,
                success: callback,
                error: function(xmlHttpRequest, textStatus, errorThrown)
                {
                    jQuery.ja.alert("Error", "There seems to be a problem connecting to the server. You can refresh the page and try again. If that does not work, please contact us.");
                    thisObj.ajaxReady(true);
                }
            });
        }
        else
        {
            this._ajaxQueue.splice(0, 0, { "type": "ajax", "url": url, "data": data, "callback": callback }); // Add to bottom of the queue
            if (!this._ajaxQueueProc) this._ajaxQueueProc = setInterval("jQuery.ja._ajaxQueueHandler()", 200);
        }
    },

    ajaxForm: function(form, callback, noQueue)
    {
        if (noQueue)
        {
            var randId = "F" + Math.floor((Math.random() * 1000000));

            while (jQuery("#" + randId).length > 0) randId = "F" + Math.floor((Math.random() * 1000000));

            var iframe = jQuery("<iframe style='width:1px;height:1px;position:absolute;left:-100px;top:-100px;overflow:hidden;' id='" + randId + "' name='" + randId + "' src=''></iframe>");

            jQuery("body").append(iframe);

            iframe.load(function()
            {
                var response = jQuery.trim(this.contentWindow.document.body.innerHTML);

                var frm = jQuery(this);
                setTimeout(function() { frm.remove() }, 300);

                if (callback) callback(response);
            });

            // Make sure browser doesn't cache
            var url = form.attr("action");
            form.attr("action", url + (url.indexOf("?") > -1 ? "&" : "?") + (new Date().valueOf()));

            form.attr("target", randId);
            form.submit();
        }
        else
        {
            this._ajaxQueue.splice(0, 0, { "type": "ajaxForm", "form": form, "callback": callback }); // Add to bottom of the queue
            if (!this._ajaxQueueProc) this._ajaxQueueProc = setInterval("jQuery.ja._ajaxQueueHandler()", 200);
        }
    },

    ajaxResult: function(result, callback)
    {
        if (result && (typeof result.error != "undefined"))
        {
            var err = result.error.toString();

            if (result.error.toString() == "-1")
            {
                jQuery.ja.alert("Error", "Unable to connect to server, please try again.");
            }
            else
            {
                if (typeof (callback) == "function")
                    callback();
                else
                    callback[result.error.toString()]();
            }
        }
    },

    alert: function()
    {
        var title = arguments.length > 1 ? arguments[0] : "";
        var content = arguments.length >= 2 ? arguments[1] : (arguments.length > 0 ? arguments[0] : "");
        var button = arguments.length > 2 ? arguments[2] : null;

        var dialog = jQuery("<div/>");

        dialog.attr("title", title);

        if (typeof content == "string")
            dialog.html(content);

        dialog.dialog(
        {
            bgiframe: true,
            resizable: false,
            modal: true,
            position: "top",
            buttons: (button ? button :
            {
                OK: function()
                {
                    jQuery(this).dialog("close");
                }
            }),
            close: function()
            {
                jQuery(this).remove();
            }
        });

        var winHeight = jQuery(window).height();
        var dialogUi = jQuery(".ui-dialog:last");

        dialogUi.css("top", 0 - dialogUi.height() - 20);

        dialogUi.animate(
        {
            top: winHeight / 2 - dialogUi.height() / 2 + jQuery(window).scrollTop()
        },
        {
            duration: "normal",
            easing: "easeOutSine"
        });
    },

    popup: function(title, content, width, button)
    {
        if (!width) width = 500;
        var dialog = jQuery("<div/>");

        dialog.attr("title", title);

        if (typeof content == "string")
            dialog.html(content);
        else if (typeof content == "object")
            dialog.append(content);

        dialog.dialog(
        {
            bgiframe: true,
            resizable: false,
            modal: true,
            position: "top",
            height: "auto",
            width: width,
            buttons: (button ? button :
            {
                OK: function()
                {
                    jQuery(this).dialog("close");
                }
            }),
            close: function()
            {
                jQuery(this).remove();
            }
        });

        var winHeight = jQuery(window).height();
        var dialogUi = jQuery(".ui-dialog");

        dialogUi.animate(
        {
            top: winHeight / 2 - dialogUi.height() / 2 + jQuery(window).scrollTop()
        },
        {
            duration: "normal",
            easing: "easeOutSine"
        });
    },

    ajaxReady: function(status)
    {
        if (status == true)
        {
            jQuery("#ajax-loader").remove();
            this._ajaxRunning = status;
        }
        else if (status == false)
        {
            jQuery("body").append("<div id='ajax-loader'><span>Loading... please wait...</span></div>");
            this._ajaxRunning = status;
        }
        else
            return this._ajaxRunning;
    },

    stylesheet: function(url)
    {
        jQuery("head").append("<link rel='stylesheet' href='" + url + "' type='text/css' />");
    },

    cookie: function(name, value, persistDays)
    {
        if (arguments.length > 1)
        {
            var expires = "";

            if (persistDays)
            {
                var date = new Date();
                date.setTime(date.getTime() + (persistDays * 24 * 60 * 60 * 1000));
                expires = "; expires=" + date.toGMTString();
            }
            else
            {
                expires = "";
            }

            if (document && document.cookie) document.cookie = name.trim() + "=" + value.trim() + expires + "; path=/";
        }
        else
        {
            var nameEQ = name + "=";
            var arr = document.cookie.split(';');

            for (var i = 0; i < arr.length; i++)
            {
                var cookie = arr[i].trim();
                var cookiePart = cookie.split('=');

                if (cookiePart.length >= 2 && cookiePart[0].trim().toLowerCase() == name.toLowerCase())
                {
                    return cookiePart[1].trim();
                }
            }

            return null;
        }
    },

    help: function(link)
    {
        var popup = jQuery(
            "<form onsubmit='return false'><div id='support-form'>" +
                "<div class='form-field-label'>Your Email:</div>" +
                "<div><input name='email' type='text' value='' tabindex='100' /></div>" +
                "<div class='form-field-label margin-top-normal'>How may we help you today?</div>" +
                "<div><textarea name='body' style='width:90%;height:200px' tabindex='101'></textarea></div>" +
            "</div></form>"
        );

        var button = {};

        button["Send"] = function()
        {
            var thisObj = this;
            var form = jQuery("#support-form");
            var email = $.trim(form.find("input:first").val());
            var body = $.trim(form.find("textarea:first").val());
            var data = { "email": email, "body": body };

            if (email.length == 0 || body.length == 0)
            {
                jQuery.ja.alert("Help", "Please enter both your email and message.");
                return;
            }
            jQuery.ja.ajax("/ajax/home/supportemail", data, function(o)
            {
                jQuery.ja.ajaxResult(o, function()
                {
                    jQuery(thisObj).dialog("close");
                    jQuery.ja.alert("Help", "Thank you for contacting us, we'll get back to you as soon as possible.");
                });
            });
        }

        button["Cancel"] = function()
        {
            jQuery(this).dialog("close");
        }

        jQuery.ja.popup("Help", popup, 500, button);
    },

    _ajaxQueueHandler: function()
    {
        if (this.ajaxReady())
        {
            var thisObj = this;
            var funcData = this._ajaxQueue.pop();

            this.ajaxReady(false);

            if (funcData.type == "ajaxForm")
            {
                var randId = "F" + Math.floor((Math.random() * 1000000));

                while (jQuery("#" + randId).length > 0) randId = "F" + Math.floor((Math.random() * 1000000));

                var iframe = jQuery("<iframe style='width:1px;height:1px;position:absolute;left:-100px;top:-100px;overflow:hidden;' id='" + randId + "' name='" + randId + "' src=''></iframe>");

                jQuery("body").append(iframe);

                iframe.load(function()
                {
                    var data = jQuery.trim(this.contentWindow.document.body.innerHTML);

                    var frm = jQuery(this);
                    setTimeout(function() { frm.remove() }, 200);

                    // Remove interval if queue is empty
                    if (thisObj._ajaxQueue.length == 0)
                    {
                        clearInterval(thisObj._ajaxQueueProc);
                        thisObj._ajaxQueueProc = null;
                    }

                    thisObj.ajaxReady(true);
                    if (funcData.callback) funcData.callback(data);
                });

                // Make sure browser doesn't cache
                var url = funcData.form.attr("action");
                funcData.form.attr("action", url + (url.indexOf("?") > -1 ? "&" : "?") + (new Date().valueOf()));

                funcData.form.attr("target", randId);
                funcData.form.submit();
            }
            else
            {
                jQuery.ajax(
                {
                    url: funcData.url,
                    data: (funcData.data ? funcData.data : {}),
                    type: "POST",
                    dataType: "json",
                    cache: false,
                    success: function(data)
                    {
                        // Remove interval if queue is empty
                        if (thisObj._ajaxQueue.length == 0)
                        {
                            clearInterval(thisObj._ajaxQueueProc);
                            thisObj._ajaxQueueProc = null;
                        }

                        thisObj.ajaxReady(true);
                        if (funcData.callback) funcData.callback(data);
                    },
                    error: function(xmlHttpRequest, textStatus, errorThrown)
                    {
                        // Remove interval if queue is empty
                        if (thisObj._ajaxQueue.length == 0)
                        {
                            clearInterval(thisObj._ajaxQueueProc);
                            thisObj._ajaxQueueProc = null;
                        }

                        thisObj.ajaxReady(true);
                        jQuery.ja.alert("Error", "There seems to be a problem connecting to the server. You can refresh the page and try again. If that does not work, please contact us.");
                    }
                });
            }
        }
    }
}

// Pagination
jQuery.fn.pagination = function(totalItem, pageSize, currentPage, callbacks)
{
    var pagination = jQuery(this);
    var totalPage = totalItem % pageSize == 0 ? Math.floor(totalItem / pageSize) : Math.floor(totalItem / pageSize + 1);

    if (totalPage < 1) totalPage = 1;

    pagination.html("");
    pagination.addClass("ui-pagination-panel");

    var display = jQuery("<span class='ui-pagination-display'>" + currentPage + " / " + totalPage + "</span>");
    var next = jQuery(totalPage > currentPage ? "<a href='javascript:;' class='ui-pagination-next'>Next</a>" : "<span class='ui-pagination-next'>Next</span>");
    var previous = jQuery(currentPage > 1 ? "<a href='javascript:;' class='ui-pagination-previous'>Previous</a>" : "<span class='ui-pagination-previous'>Previous</span>");

    pagination.append(previous).append(display).append(next);

    if (currentPage > 1)
    {
        previous.click(function()
        {
            if (currentPage > 1 && callbacks["previous"] && typeof callbacks["previous"] == "function") callbacks["previous"](currentPage - 1);
            pagination.pagination(totalItem, pageSize, currentPage - 1, callbacks);
        });
    }

    if (totalPage > currentPage)
    {
        next.click(function()
        {
            if (totalPage > currentPage && callbacks["next"] && typeof callbacks["next"] == "function") callbacks["next"](currentPage + 1);
            pagination.pagination(totalItem, pageSize, currentPage + 1, callbacks);
        });
    }

    return pagination;
}

// Expandable textbox
jQuery.fn.expandableTextBox = function(minHeight, maxHeight, resizeCallback)
{
    function __resize(box)
    {
        var newBox = box.clone();

        newBox.attr("style", "height:0px;width:" + box.width() + "px;position:absolute;left:-1000px;top:-1000px;");

        jQuery("body").append(newBox);
        newBox.val(box.val())

        var height = newBox.height();
        var scrollHeight = newBox.attr("scrollHeight");

        if (scrollHeight > height)
        {
            box.css("height", (minHeight && scrollHeight < minHeight ? minHeight : (maxHeight && scrollHeight > maxHeight ? maxHeight : scrollHeight)));
        }

        newBox.remove();
    }

    jQuery(this).keyup(function()
    {
        var box = jQuery(this);
        __resize(box);
        if (resizeCallback) resizeCallback(box);
    }).blur(function()
    {
        jQuery(this).keyup();
    });

    __resize(jQuery(this));
}

// Popup list
jQuery.fn.dropDownList = function()
{
    var select = jQuery(this);

    if (select.attr("tagName").toLowerCase() == "select")
    {
        select.hide();

        var onchange = arguments[0];

        if (select.data("ui"))
        {
            // Update existing ui
            var list = select.data("ui");
            var container = list.find(".ui-drop-down-list-panel-content");

            container.html("");
            select.find("option").each(function()
            {
                var option = jQuery(this);
                var item = jQuery("<div class='ui-drop-down-list-item'/>");

                item.data("value", option.val()).text(option.text()).click(function()
                {
                    var obj = jQuery(this);
                    var mainList = obj.parents(".ui-drop-down-list");

                    mainList.find("> .ui-drop-down-list-display > span:eq(1)").text(obj.text());
                    mainList.data("value", obj.data("value"));

                    mainList.removeClass("ui-drop-down-list-active");
                    mainList.find(".ui-icon").removeClass("ui-icon-triangle-1-s").addClass("ui-icon-triangle-1-w");

                    mainList.data("element").val(obj.data("value"));

                    if (typeof onchange == "function") onchange(obj.text(), obj.data("value"));
                });

                container.append(item);

                if (option.attr("selected"))
                {
                    list.find("> .ui-drop-down-list-display > span:eq(1)").text(option.text());
                    item.addClass("ui-drop-down-list-selected");
                }
            });
        }
        else
        {
            // Create new UI
            var list = jQuery("<div class='ui-drop-down-list float-left'/>");
            var panel = jQuery("<div class='ui-drop-down-list-panel'/>");
            var container = jQuery("<div class='ui-drop-down-list-panel-content'/>");

            list.prepend("<div class='ui-drop-down-list-display'><span class='ui-icon ui-icon-triangle-1-w float-right'></span><span></span><span class='clear-both'></span></div>");

            select.after(list.append(panel.append(container)));

            select.find("option").each(function()
            {
                var option = jQuery(this);
                var item = jQuery("<div class='ui-drop-down-list-item'/>");

                item.data("value", option.val()).text(option.text()).click(function()
                {
                    var obj = jQuery(this);
                    var mainList = obj.parents(".ui-drop-down-list");

                    mainList.find("> .ui-drop-down-list-display > span:eq(1)").text(obj.text());
                    mainList.data("value", obj.data("value"));

                    mainList.removeClass("ui-drop-down-list-active");
                    mainList.find(".ui-icon").removeClass("ui-icon-triangle-1-s").addClass("ui-icon-triangle-1-w");

                    mainList.data("element").val(obj.data("value"));

                    if (typeof onchange == "function") onchange(obj.text(), obj.data("value"));
                });

                container.append(item);

                if (option.attr("selected"))
                {
                    list.find("> .ui-drop-down-list-display > span:eq(1)").text(option.text());
                    item.addClass("ui-drop-down-list-selected");
                }
            });

            select.data("ui", list);

            // List events
            list.mouseover(function()
            {
                var obj = jQuery(this);

                obj.addClass("ui-drop-down-list-active");
                obj.find(".ui-icon").removeClass("ui-icon-triangle-1-w").addClass("ui-icon-triangle-1-s");

                var winHeight = jQuery(window).height();
                var scrollTop = jQuery(window).scrollTop();
                var offset = obj.offset();
                var panelHeight = panel.height();
                var displayHeight = obj.height();

                panel.css("left", offset.left);
                panel.css("min-width", obj.width() - 2);

                if (winHeight + scrollTop <= offset.top + displayHeight + panelHeight)
                    panel.css("top", offset.top - panelHeight - 1);
                else
                    panel.css("top", offset.top + displayHeight - 1);

            }).mouseout(function()
            {
                var obj = jQuery(this)
                obj.removeClass("ui-drop-down-list-active");
                obj.find(".ui-icon").removeClass("ui-icon-triangle-1-s").addClass("ui-icon-triangle-1-w");
            }).data("element", select);

            list.after("<div class='clear-both'></div>");
        }
    }
}

jQuery.fn.checkBoxList = function(options)
{
    var panel = jQuery(this);

    if (!options) options = {};

    if (!panel.data("_checkBoxList"))
    {
        panel.find("> label").each(function(index)
        {
            var item = jQuery(this);

            item.data("index", index).data("value", item.html());

            item.addClass("ui-checkbox-list-option").click(function()
            {
                var opt = jQuery(this);

                if (!opt.data("checked"))
                {
                    if (options.exclusive === true)
                    {
                        opt.parent().find("> label").each(function()
                        {
                            var tag = jQuery(this);
                            tag.find("span:first").remove();
                            tag.data("checked", false).removeClass("ui-checkbox-list-option-checked");
                        });
                    }

                    opt.html("<span class='ui-icon-dark-gray ui-icon-check' style='position:absolute;left:2px;top:3px;'></span>" + opt.html()).addClass("ui-checkbox-list-option-checked");
                    opt.data("checked", true);
                }
                else
                {
                    var checked = 2;

                    if (options.required === true)
                    {
                        checked = 0;
                        opt.parent().find("> label").each(function()
                        {
                            var otherOpt = jQuery(this);
                            if (otherOpt.data("checked")) checked++;
                        });
                    }

                    if (checked > 1)
                    {
                        opt.find("span:first").remove();
                        opt.removeClass("ui-checkbox-list-option-checked");
                        opt.data("checked", false);
                    }
                }

                if (typeof options.click == "function") options.click(opt);
            });
        });

        panel.data("_checkBoxList", true);
    }

    // Clear all checked item
    if (options.clear == true)
    {
        panel.find("> label").each(function()
        {
            var item = jQuery(this);
            if (item.data("checked")) item.trigger("click");
        });
    }

    // Loop through each item
    this.eachOption = function(func)
    {
        if (typeof func != "function") return;

        var panel = jQuery(this);

        panel.find("> label").each(function()
        {
            func(jQuery(this));
        });
    }

    // Get/set checked
    this.checked = function(index)
    {
        var panel = jQuery(this);

        if (typeof index == "number")
        {
            var item = panel.find("> label:eq(" + index + ")");
            if (!item.data("checked")) item.trigger("click");
        }
        else if (typeof index == "object" && index.length != null)
        {
            panel.find("> label").each(function(idx)
            {
                for (var i = 0; i < index.length; i++)
                {
                    if (idx == index[i])
                    {
                        var item = jQuery(this);
                        if (!item.data("checked")) item.trigger("click");
                    }
                }
            });
        }
        else
        {
            var list = new Array();

            panel.find("> label").each(function()
            {
                var obj = jQuery(this);
                if (obj.data("checked")) list.push(obj);
            });

            return list;
        }
    };

    return this;
}

// Extend String object functionalities
String.prototype.startsWith = function(str, caseSensitive)
{
    return (new RegExp("^" + RegExp.escape(str), (caseSensitive ? "" : "i") + "g").test(this));
}

String.prototype.endsWith = function(str, caseSensitive)
{
    return (new RegExp(RegExp.escape(str) + "jQuery", (caseSensitive ? "" : "i") + "g").test(this));
}

String.prototype.toInt = function()
{
    return parseInt(this);
}

String.prototype.toFloat = function()
{
    return parseFloat(this);
}

String.prototype.format = function()
{
    var formatted = this;

    for (var i = 0; i < arguments.length; i++)
    {
        formatted = formatted.replace(new RegExp("[{][" + i + "][}]", "ig"), arguments[i]);
    }

    return formatted;
}

// Extend RegExp object functionalities
RegExp.escape = function(text)
{
    var chars = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\'];
    return text.replace(new RegExp("(\\" + chars.join("|\\") + ")", "g"), "\\jQuery1");
}
