﻿/// <reference path="jquery-1.2.6.js" />

/**
* Wrapper for our Ajax request.
* It assumes the service is returning a JSON object created by our .Net ServiceResponse
* The config object has the following parameters:
* @param {string} service The name of the asmx (without the extension. ex. "ProgramService")
* @param {string} methodName The name of the method to be called on the web service
* @param {object} data (optional) The parameters to be passed to the Ajax request
* @param {function} success (optional) The callback function to be called, will be called with 1 parameter,
    either the json result from the server or the html from the response if that dataType is selected
* @param {object} scope (optional) The scope in which the success method should be called
* @param {boolean} showErrorMessage (optional) defaults to true. Sets whehter or not to inform the user on errors
* @return {void}
*/
AjaxRequest = function(obj) {
    var cb = obj.success;
    var scope = obj.scope;
    var showErrorMessage = !(obj.showErrorMessage === false);
    var errorCb = obj.error;

    var url = "/WebServices/" + obj.service + ".asmx/" + obj.methodName;
    $.ajax({
        async: true,
        dataType: "json",
        url: url,
        data: obj.data,
        error: function(request, textStatus, errorThrown) {
            onErrorResponse("Error",
            "There was an error processing that request.",
            errorCb);
        },
        success: function(json, textStatus) {
            if (!json.success)
                onErrorResponse(json.header, json.message, errorCb);
            else {
                if (cb != null) {
                    if (!scope)
                        cb(json.data);
                    else
                        cb.apply(scope, [json.data]);
                }
            }
        },
        complete: obj.complete
    });

    function onErrorResponse(header, message, cb) {
        if (showErrorMessage)
            alert(header + ": " + message);

        if (cb != null) cb();
    }
};

$.extend({
    inpAjax: function(config) {
        config.service = "inPractice";
        AjaxRequest(config);
    },
    
    equalizeHeights: function(colaName, colbName, modifier) {
        if ($(colbName).height() < $(colaName).height()) {
            $(colbName + modifier).height($(colaName).height() - $(colbName).height());
        }
        else {
            $(colaName + modifier).height($(colaName).height() - $(colbName).height());
        }
    }
});

// Html generator
html = {
    generator: function(children, tag, attributes, events) {
        var item = $("<" + tag + "/>");
        return this.itemGenerator(children, item, attributes, events);
    },
    itemGenerator: function(children, item, attributes, events) {
        if (attributes) {
            for (var i in attributes) {
                item.attr(i, attributes[i]);
            }
        }
        if (events) {
            for (var i in events) {
                item[i](events[i]);
            }
        }
        if (children) {            
            $(item).appendAll($.makeArray(children));
        }
        return item;        
    },
    a: function(children, href, classes, click) {
        return this.generator(children, "a", { href: href, "class": classes }, { click: click });
    },
    img: function(src, alt, classes, click) {
        return this.generator(null, "img", { src: src, alt: alt, "class": classes }, { click: click });
    },
    form: function(children, classes, submit) {
        return this.generator(null, "form", { "class": classes }, { submit: submit });
    },
    select: function(options, classes, isMultiple) {
        var attributes = { "class": classes }
        if (isMultiple) { attributes.multiple = "multiple"; }
        return this.generator(options, "select", attributes);
    },
    option: function(value, text) {
        return this.generator(text, "option", { value: value });
    },
    input: function(type, value, classes, click) {
        return this.itemGenerator(null, $("<input type=\"" + type + "\" />"), { value: value, "class": classes }, { click: click });
    },
    h: function(text, level, classes, click) {
        return this.generator(text, "h" + level, { "class": classes }, { click: click });
    },
    label: function(text, forControl, classes, click) {
        return this.generator(text, "label", { "for": forControl, "class": classes }, { click: click });
    },
    ul: function(listItems, classes) {
        return this.generator(listItems, "ul", { "class": classes });
    },
    ol: function(listItems, classes) {
        return this.generator(listItems, "ol", { "class": classes });
    },
    li: function(text, value, classes, click) {
        return this.generator(text, "li", { "class": classes, value: value }, { click: click });
    },
    // for intellisense
    submit: function(value, classes, click) { },
    button: function(value, classes, click) { },
    checkbox: function(value, classes, click) { },
    radio: function(value, classes, click) { },
    text: function(value, classes, click) { },
    textarea: function(value, classes, click) { },
    span: function(children, classes, click) { },
    div: function(children, classes, attributes, click) { },
    p: function(children, classes, click) { },
    em: function(children, classes, click) { },
    strong: function(children, classes, click) { }
};

var tags = ["span", "p", "em", "strong"];
$(tags).each(function(i, tag) {
    html[tag] = function(children, classes, click) {
        return html.generator(children, tag, { "class": classes }, { click: click });
    }
});

var tagsAttributes = ["div"];
$(tagsAttributes).each(function(i, tag) {
    html[tag] = function(children, classes, attributes, click) {
        if (!attributes)
            attributes = {};
        attributes["class"] = classes;
        return html.generator(children, tag, attributes, { click: click });
    }
});

var types = ["submit", "button", "checkbox", "radio", "text", "textarea"];
$(types).each(function(i, type) {
    html[type] = function(value, classes, click) {
        return html.input(type, value, classes, click);
    }
});

$.fn.extend({
    modalDialogOpener: function(openFunc, closeFunc, noPadding) {
        return this.each(function() {
            $(this).click(function(e) {
                var md = "#modalDialog";
                var el = $(this)
                var spinner = $(md + "Spinner");
                spinner.show();

                var content = $(md + "Content").html("");
                if (noPadding === undefined) { content.addClass("modalContent"); }
                var title = $(md + "Title").html(el.attr("title"));
                var footer = $(md + "Footer").html("").hide();

                jqmHideFunc = closeFunc; // global close func
                openFunc(el, content, title, spinner, footer); 

                $(md).jqmShow();
                return false;
            });
        });
    },

    multiList: function(loadFn, saveFn) {
        var btnHelper = {
            button: function(text, clickEvent, buttonClass) {
                if (buttonClass == null) { buttonClass = "mlArrow"; }
                return html.p(text, buttonClass, clickEvent);
            },
            leftRightButton: function(text, sourceMultiSelect, destMultiSelect) {
                return this.button(text, function() {
                    $(sourceMultiSelect).find("option:selected").remove().appendTo(destMultiSelect);
                    return false;
                });
            },
            upDownButton: function(text, multiList, isDown) {
                return this.button(text, function() {
                    var selected = $(multiList).find("option:selected");
                    if (isDown) {
                        selected = selected.reverse()
                    }
                    selected.each(function() {
                        if (isDown) {
                            $(this).next().remove().insertBefore(this);
                        } else {
                            $(this).prev().remove().insertAfter(this);
                        }
                    });
                    return false;
                });
            }
        };

        $(this).each(function() {
            var leftSelect = html.select(null, "ml", true);
            var rightSelect = html.select(null, "ml", true);

            var context = this;
            $(this).appendAll([
                html.div([
                    leftSelect,
                    html.div([
                        btnHelper.leftRightButton("&rarr;", leftSelect, rightSelect),
                        btnHelper.leftRightButton("&larr;", rightSelect, leftSelect)
                    ], "left arrowSection", null),
                    rightSelect,
                    html.div([
                        btnHelper.upDownButton("&uarr;", rightSelect, false),
                        btnHelper.upDownButton("&darr;", rightSelect, true)
                    ], "left arrowSection", null),
                ]),
                html.div([
                    html.submit("Save Changes", "", function() { context.save(); return false; })
                ], "clear")
            ]);

            function appendOptions(select, options, text, value) {
                for (var i in options) {
                    select.append(html.option(options[i][value], options[i][text]));
                }
            }

            loadFn(function(items, callback) {
                appendOptions(leftSelect, items.left, items.text, items.value);
                appendOptions(rightSelect, items.right, items.text, items.value);
                if (callback) { callback(); }
            });

            this.save = function() {
                saveFn(rightSelect.find("option"));
            }
        });
        return this;
    },

    appendAll: function(elements) {
        for (var i = 0; i < elements.length; i++) {
            $(this).append(elements[i]);
        }
        return this;
    },

    reverse: function() {
        var reversedArr = [];

        $(this).each(function() {
            reversedArr.push(this);
        });
        return $(reversedArr.reverse());
    },

    fadeOutAndIn: function(html, cbFunc) {
        $(this).each(function() {
            $(this).fadeOut("normal", function() {
                $(this).fadeIn().html(html);
                if (cbFunc != null) { cbFunc(); }
            });
            return this;
        });
    },

    replacePanel: function(cbFunc) {
        $(this).replacePartial("Cco.Website" + $(this).attr("name") + ", CCO.Website", {}, cbFunc);
    },

    replacePartial: function(source, parameters, cbFunc) {
        var context = this;
        $.inpAjax({
            methodName: "GetPartial",
            data: { source: source, parameters: parameters },
            success: function(html) {
                $(context).fadeOutAndIn(html, cbFunc);
            }
        });
    },

    validateEmail: function() {
        var regex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
        var fieldOK = this.val().match(regex);

        if (fieldOK) {
            if (inPractice.hasBeenValidated) {
                this.removeClass("error");
                this.addClass("success");
            }
        }
        else {
            inPractice.hasBeenValidated = true;
            this.removeClass("success");
            this.addClass("error");
        }

        return fieldOK;
    }
});