/*global window*/
(function (window) {
    "use strict";
    var $ = window.jQuery,
        view = {},
        model = {},
        imagesReady = false,
        boxHeight = false,
        ua = window.navigator.userAgent;

    view = {

        puff: {

            info: {

                show: function show(e) {
                    e.preventDefault();

                    var that = this,
                        t = $(that),
                        text = t.data("text"),
                        mod = t.data("modal"),
                        newId = "",
                        top = function top() {
                            var dims = $.getDimensions(that);
                            return parseInt(dims.top + dims.fullHeight + 10, 10) + "px";
                        },
                        left = function left() {
                            var dims = $.getDimensions(that);
                            return parseInt(dims.left, 10) + "px";
                        };

                    if (!mod) {
                        $(".infoModal").hide();

                        newId = $.uniqueId("modalInfo_");

                        document.body.appendChild($.create({
                            className: "infoModal",
                            innerHTML: text,
                            id: newId,
                            top: top(),
                            left: left(),
                            append: {
                                tagName: "a",
                                className: "close",
                                click: function (e) {
                                    e.preventDefault();

                                    $(this).closest(".infoModal").hide();
                                }
                            }
                        }));

                        mod = t.data("modal", $("#" + newId));

                        $(window).resize(function () {
                            $("#" + newId).css({
                                top: top(),
                                left: left()
                            });
                        });

                    } else {

                        $(".infoModal").hide();

                        mod.toggle();
                    }
                },

                icon: function () {

                    var that = this,
                        t = $(that),
                        text = that.value,
                        box = t.closest("div.box");

                    if (text) {
                        box.append($.create({
                            tagName: "a",
                            className: "icon",
                            href: "/",
                            innerHTML: "i",
                            click: view.puff.info.show,
                            data: {
                                "text": text
                            }
                        }));
                    }

                },

                init : function () {
                    $(".box input[type=hidden]").each(view.puff.info.icon);
                }
            }

        },

		 rankingList: {
            isRunning : false,
            init : function () {
                
                if (!view.rankingList.isRunning) {
                    view.rankingList.isRunning = true;

                    var rankingList = $(".ranking ul").find("> li:nth-child(4), > li:nth-child(4) + li"),
                        splitUl = $.create({
                            tagName: "ul"
                        }),
                        updatePanel = $("#ctl00_MainRegion_Result_ctl00"),
                        hasChangedDOM = updatePanel.data("hasChangedDOM");

                    if (rankingList.length && rankingList.length > 1) {
                        splitUl.appendChild(rankingList[0]);
                        splitUl.appendChild(rankingList[1]);

                        $(".ranking ul").after(splitUl);
                        $(".ranking ul + ul").after("<div class=\"cb\" />");
                    }

                    if (updatePanel.length && (!hasChangedDOM || (hasChangedDOM && !hasChangedDOM["rankingList"]))) {
                        $("#ctl00_MainRegion_Result_ctl00").changedDOM(view.rankingList.init, "rankingList");
                    }

                    setTimeout(function () {
                        view.rankingList.isRunning = false;
                    }, 100);
                }
            }
        },

        ranking: {

            sunSet: function () {

                /*  
                DO NOT REMOVE. Save for future reference.
                
                if (rank >= 0 && rank <= 105) {
                ret = "4";
                } else if (rank >= 106 && rank <= 210) {
                ret = "3";
                } else if (rank >= 211 && rank <= 315) {
                ret = "2";
                } else if (rank >= 316 && rank <= 420) {
                ret = "1";
                }
                */

                var that = this,
                    ih = that.innerHTML,
                    rank = parseInt($.trim(ih.replace(/\/[\w]+$/, "")), 10) ? parseInt($.trim(ih.replace(/\/[\w]+$/, "")), 10) : 0,
                    suns = rank ? (
                        (rank >= 699 && rank <= 930) ? 1 : (
                            (rank >= 466 && rank <= 698) ? 2 : (
                                (rank >= 233 && rank <= 465) ? 3 : (
                                    (rank >= 0 && rank <= 232) ? 4 : 0
                                )
                            )
                        )
                    ) : 0,
                    i = 0,
                    l = 4,
                    sunSpan = function (i) {
                        that.appendChild($.create({
                            tagName: "span",
                            className: function () {

                                var cn = "sun";

                                if (i >= suns) {
                                    cn += " totaleclipse";
                                }

                                return cn;
                            }
                        }));
                    };

                that.innerHTML = "";

                for (i = 0; i < l; i += 1) {
                    sunSpan(i);
                }
            },

            init_0: function () {

                $("tr.ranking td").each(view.ranking.sunSet);
            }

        },

        egualHeight: {

            setHeight: function () {

                var that = this,
                    t = $(that),
                    height = t.height(),
                    cols = t.find("> .col");

                cols.parent().css("min-height", height + "px");
                cols.css("min-height", height + "px");

            },

            boxHeight: function () {

                var boxes = $("div.equalHeight[class*=Cols] > .col > .box"),
                    i = 0,
                    l = boxes.length,
                    maxheight = 0,
                    cHeight = 0;

                if ($.isEPIEditMode) {
                    boxHeight = true;
                    return;
                }

                if (l) {

                    for (i = 0; i < l; i += 1) {

                        cHeight = $.getDimensions(boxes[i]).height;

                        if (!maxheight || (maxheight && (cHeight > maxheight))) {
                            maxheight = cHeight;
                        }
                    }

                    boxes.css("min-height", maxheight + "px");

                    boxHeight = true;

                } else {
                    boxHeight = true;
                    return;
                }

            },

            init: function () {

                $.runWhenExists(function () {
                    if (!document.images.length) {
                        imagesReady = true;
                    }
                    return imagesReady;
                }, function () {

                    view.egualHeight.boxHeight();

                    $.runWhenExists(function () {
                        return boxHeight;
                    }, function () {
                        $(".equalHeight").each(view.egualHeight.setHeight);
                    });


                });
            }
        },

        colWidthFix: {

            checkWidth: function () {

                var that = this,
                    t = $(that),
                    pnWidth = t.parent().width(),
                    cWidth = 0,
                    allCols = t.parent().find("> .col"),
                    i = 0,
                    l = allCols.length,
                    addPx = 0;

                for (i = 0; i < l; i += 1) {
                    cWidth += $.getDimensions(allCols[i]).fullWidth;
                }

                addPx = Math.floor((pnWidth - cWidth) / l);

                allCols.css("width", function () {
                    var w = $(this).width();

                    return parseInt(w + addPx, 10) + "px";
                });

            },

            init : function () {

                if ((/Opera/).test(ua)) {
                    $(".col:first-child").each(view.colWidthFix.checkWidth);
                }

            }

        },

        tableWidth: {

			hideGroups : function (currentTable) {
				currentTable.find("tbody.group").addClass("inActive");
			},
			
			setWidth : function setWidth(currentTable) {

				var thtd = currentTable.find("thead > tr").find("> th, > td");

				thtd.each(function (i) {
					var that = this,
						t = $(that),
						table = t.closest("table"),
						colGroup = table.find("colgroup");

					if (!colGroup.length) {
						table.prepend($.create({
							tagName : "colgroup"
						}));

						colGroup = table.find("colgroup");
					}

					colGroup.append($.create({
						tagName : "col",
						width : that.offsetWidth + "px"
					}));

					if (i === (thtd.length - 1)) {
						view.tableWidth.hideGroups(currentTable);
					}
				});

				if ($.isIE7) {
					currentTable.find("th:empty, td:empty").append($.create({
						tagName : "br"
					}));
				}
			},

            init : function () {

                var table = $(".compareList table"),
                    tableWidthOk = function (currentTable) {
                        //$.log(table.width(), table.parent().width());
                        return (currentTable.width() <= currentTable.parent().width());
                    },
                    replaces = [{
                        regexp: /(\S)(\-)(\S)/g,
                        replace: "$1- $3"
                    }, {
                        regexp: /(\S)(arbetsmarknadsdagar|represent|kommunikation|programmet)/g,
                        replace: "$1- $2"
                    }, {
                        regexp: /(\S)(h\u00F6gskola|organisation|utbildning)/g,
                        replace: "$1- $2"
                    }, {
                        regexp: /(\S)(vetenskap|verksamhet|studerande)/g,
                        replace: "$1- $2"
                    }, {
                        regexp: /(\S)(program|projekt|ekonomi|utveckling|f\u00F6reningen)/g,
                        replace: "$1- $2"
                    }, {
                        regexp: /(fadder)(f\u00D6retags)/gi,
                        replace: "$1- $2"
                    }, {
                        regexp: /(\S{3,})(\_)(\S{3,})/g,
                        replace: "$1$2 $3"
                    }],
                    i = 0,
                    l = replaces.length,
                    each = function (currentTable, repl) {
                        currentTable.find("th, td").each(function () {
                            var that = this,
                                ih = that.innerHTML.replace(repl.regexp, repl.replace);

                            that.innerHTML = ih;
                        });
                    };


                if (table.length) {

                    table.each(function () {

                        var currentTable = $(this);

                        for (i = 0; i < l; i += 1) {
                            each(currentTable, replaces[i]);

                            if (tableWidthOk(currentTable)) {
								view.tableWidth.setWidth(currentTable);
                                break;
                            }
                        }
                    });
                }
            }
        },

        utilLinks: {

            tipsPop: {

                setPosition: function setPosition(that, popUp) {

                    var dim = $.getDimensions(that),
                        pDim = $.getDimensions(popUp);

                    $(popUp).css({
                        top: function () {
                            return parseInt(dim.top + dim.fullHeight, 10) + "px";
                        },
                        left: function () {
                            return Math.ceil(dim.left - ((pDim.fullWidth / 2) - dim.fullWidth / 2)) + "px";
                        },
                        visibility: "visible"
                    });

                    $(window).resize(function () {
                        view.utilLinks.tipsPop.setPosition(that, popUp);
                    });

                },

                validateForm: function (form) {
                    var fields = form.find("input[type=text], textarea"),
                        validEmail = /\w+([\-+.']\w+)*@\w+([\-.]\w+)*\.\w+([\-.]\w+)*/,
                        isEmail = /(^|\s)(email)(\s|$)/,
                        filedValidCount = 0,
                        receiverEmail = "",
                        message = "",
                        senderName = "",
                        senderEmail = "";

                    fields.each(function () {

                        var that = this,
                            t = $(this),
                            val = that.value,
                            setVar = function () {
                                var id = that.id,
                                    isReceiverEmail = /ReceiverMail$/,
                                    isMessage = /Message$/,
                                    isSenderName = /SenderName$/,
                                    isSenderMail = /SenderMail$/;

                                if ((isMessage).test(id)) {
                                    message = val;
                                } else if ((isReceiverEmail).test(id)) {
                                    receiverEmail = val;
                                } else if ((isSenderName).test(id)) {
                                    senderName = val;
                                } else if ((isSenderMail).test(id)) {
                                    senderEmail = val;
                                }

                            };

                        if (!val) {
                            t.parent().find("span[id$=RequiredValidator], span[id$=SenderNameValidator]").show();
                        } else {
                            t.parent().find("span[id$=RequiredValidator], span[id$=SenderNameValidator]").hide();
                            filedValidCount += 1;
                            setVar();
                        }

                        if (val && (this.className && (isEmail).test(this.className))) {

                            if (filedValidCount) {
                                filedValidCount -= 1;
                            }

                            if (!(validEmail).test(val)) {
                                t.parent().find("span[id$=MailValidator]").show();
                            } else {
                                t.parent().find("span[id$=MailValidator]").hide();
                                filedValidCount += 1;
                                setVar();
                            }
                        }

                    });

                    if (filedValidCount === fields.length) {

                        //$.log(receiverEmail, message, senderName, senderEmail);
                        model.addToQueue(false, ["SendMail", { mailSubject: "Ett tips fran hogskolekvalitet.se", mailBody: message, senderName: senderName, senderEmail: senderEmail, receiverEmail: receiverEmail}], function (data) {
                            //$.log(data);
                        });
                    }
                },

                init : function () {

                    $("body").delegate("p.utilLinks > a.tip", "click", function (e) {
                        e.preventDefault();

                        var that = this,
                            href = that.href,
                            popUp = $("#emailTip").length ? $("#emailTip") : $.create({
                                tagName: "div",
                                id: "emailTip",
                                className: "show"
                            }),
                            toggle = function (t, that, triggerIsSame) {

                                if (triggerIsSame) {
                                    if (t.hasClass("show")) {
                                        t.replaceClass("show", "hide");
                                    } else {
                                        t.replaceClass("hide", "show");
                                    }
                                } else {
                                    t.replaceClass("hide", "show");
                                    view.utilLinks.tipsPop.setPosition(that, popUp[0]);

                                    $(popUp).data("trigger", that);
                                }
                            };

                        if (popUp.tagName) {
                            document.body.appendChild(popUp);

                            $(popUp).data("trigger", that);

                            $(popUp).load(href + " .emailTip");

                            $.runWhenExists(function () {
                                return $("#emailTip .emailTip div.button").length;
                            }, function () {
                                view.utilLinks.tipsPop.setPosition(that, popUp);

                                $("#emailTip .emailTip div.button").append($.create({
                                    tagName: "input",
                                    type: "button",
                                    value: "Skicka",
                                    click: function () {

                                        var form = $(this).closest("#emailTip");

                                        view.utilLinks.tipsPop.validateForm(form);
                                    }
                                })).find("a[id$=BTNSend]").remove();

                                $(popUp).find("input:first").focus();
                            });

                        } else {

                            $("#emailTip").each(function () {
                                var that2 = this,
                                    t = $(that2);

                                t.find("input:first").focus();

                                toggle(t, that, (that === $(popUp).data("trigger")));

                            });

                        }

                    });
                }
            },

            init: function (e) {

                var updatePanel = $("#ctl00_MainRegion_Result_ctl00"),
                    hasChangedDOM = updatePanel.data("hasChangedDOM");

                if (e && e.stopPropagation) {
                    e.stopPropagation();
                }

                if (!e && window.event) {
                    window.event.cancelBubble = true;
                }

                if (!document.getElementById("prinLink")) {
                    $(".utilLinks").append($.create({
                        tagName: "a",
                        href: "/",
                        id: "prinLink",
                        className: "smallIcon print",
                        click: function (e) {
                            e.preventDefault();

                            window.print();
                        },
                        innerHTML: "<span> <!-- --> </span><span>Skriv ut</span>"
                    }));
                }

                /*if (updatePanel.length && (hasChangedDOM && !hasChangedDOM.utilLinks)) {

                    updatePanel.changedDOM(view.utilLinks.init, "utilLinks");
                }*/
            }

        },

        empty: {
            init : function () {
                $("p:empty").each(function () {
                    var t = $(this);
                    if (parseInt(t.css("margin-bottom"), 10)) {
                        t.css("margin-bottom", "0");
                    }
                });
            }
        },

        checkedRadioList: {
            init : function () {

                var setChecked = function (e) {
                    
                    if (e && e.stopPropagation) {
                        e.stopPropagation();
                    }

                    if (!e && window.event) {
                        window.event.cancelBubble = true;
                    }

                    $(".sortby input[checked]").closest("li").addClass("checked");
                };

                setChecked();

                if (!$.isIE7) {
                    $("body").delegate(".sortby ul *", "click", function (e) {

                        e.stopPropagation();

                        var that = this,
                            t = $(that);

                        if ((/^li$/i).test(that.tagName)) {
                            t.find("input").click();
                        }
                    });
                }

                $.runWhenExists(function () {
                    return $("body").hasClass("ready");
                }, function () {
                    var updatePanel = $("#ctl00_MainRegion_Result_ctl00"),
                        hasChangedDOM = updatePanel.data("hasChangedDOM");

                    /*if (updatePanel.length && (!hasChangedDOM || (hasChangedDOM && !hasChangedDOM["checkedRadioList"]))) {
                        updatePanel.changedDOM(setChecked, "checkedRadioList");
                    }*/
                });

            }

        },

        payCheck: {
            init : function () {
                $("div.payCheck").each(function () {

                    var that = this,
                        t = $(that),
                        spans = t.find("span"),
                        span = spans.length ? spans.get(0) : 0,
                        newSpan = span ? spans.clone() : null;

                    if (newSpan) {
                        newSpan.css("left", span.offsetLeft);
                        t.prev().append(newSpan);
                    }

                    that.parentNode.insertBefore(that, that.parentNode.firstChild);

                });
            }
        },

        tabs: {
            init : function () {

                $.storeScrollPos = 0;

                var tabs = $("form > ul");

                tabs.normalize();

                tabs.css({
                    "width": function () {
                        var dims = $.getDimensions(this);
                        if (!$.isIE) {
                            return dims.fullWidth + "px";
                        } else {
                            return "auto";
                        }
                    }
                });

                tabs.delegate("*", "click", function (e) {

                    if (e && e.preventDefault) {
                        e.preventDefault();
                    }

                    if (e && e.stopPropagation) {
                        e.stopPropagation();
                    }

                    var that = this,
                        t = $(that),
                        ulDims = $.getDimensions(t.closest("ul").get(0)),
                        show = function () {
                            var pnDims = $.getDimensions(that.parentNode),
                                href = that.href,
                                doc = $.create({
                                    id: "tabDoc",
                                    width: 0,
                                    className: "hide",
                                    top: function () {
                                        if ($.isIE) {
                                            return parseInt(ulDims.ofs.top + pnDims.margin.left, 10) + "px";
                                        } else {
                                            return parseInt(ulDims.ofs.top + ulDims.fullHeight + pnDims.margin.left, 10) + "px";
                                        }
                                    }
                                }),
                                docWrap = $("#docWrap"),
                                tabDoc = null,
                                resize = function (animate) {

                                    var dwDims = $.getDimensions(docWrap.get(0)),
                                        toLeft = parseInt(dwDims.left + dwDims.width, 10),
                                        toWidth = ($.isIE && !$.isIE9) ? parseInt((toLeft - ulDims.fullWidth) + 3, 10) : ($.isIE9 ? parseInt((toLeft - ulDims.fullHeight) + 1, 10) : parseInt((toLeft - ulDims.fullHeight) + 3, 10)),
                                        time = 10,
                                        iv = null,
                                        scrollReady = false,
                                        slowScroll = function () {
                                            var st = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop,
                                                newSt = (st - 30);

                                            if (st > 0) {
                                                window.scrollTo(newSt, newSt);
                                            } else {
                                                window.scrollTo(0, 0);
                                                scrollReady = true;
                                                clearInterval(iv);
                                            }
                                        };

                                    if (animate && animate === "animate") {
                                        $.storeScrollPos = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
                                    }

                                    if (document.documentElement.scrollTop || document.body.scrollTop) {
                                        scrollReady = false;
                                        iv = setInterval(slowScroll, time);
                                    } else {
                                        scrollReady = true;
                                    }

                                    $.runWhenExists(function () {
                                        return scrollReady;
                                    }, function () {
                                        if (animate && animate === "animate") {
                                            tabs.css("position", "absolute").animate({
                                                left: toLeft + "px"
                                            }, "slow");

                                            tabDoc.css("display", "block").animate({
                                                width: toWidth + "px",
                                                minHeight: 300
                                            }, "slow");
                                        } else {
                                            tabs.css({
                                                left: toLeft + "px"
                                            });

                                            tabDoc.css({
                                                width: toWidth + "px"
                                            });
                                        }
                                    });


                                };

                            if (!$("#tabDoc").length) {
                                document.body.appendChild(doc);
                            }

                            tabDoc = $("#tabDoc");

                            tabDoc.load(href + " .fullWidth .article", function () {
                                view.readMore.init("#tabDoc .article h2 + p");
                            });
                            tabDoc.append("<div class=\"cb\" />");

                            resize("animate");


                            $(window).resize(resize);

                        },
                        hide = function () {

                            $(window).unbind("resize");

                            var iv = null,
                                slowScroll = function () {
                                    var st = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop,
                                        newSt = parseInt(st + 30, 10);

                                    if (newSt < $.storeScrollPos) {
                                        window.scrollTo(0, newSt);
                                    } else {
                                        window.scrollTo(0, $.storeScrollPos);
                                        clearInterval(iv);
                                    }
                                };

                            tabs.animate({
                                left: 0
                            }, "slow", function () {
                                $(this).css("position", "fixed");
                            });

                            $("#tabDoc").animate({
                                width: 0
                            }, "slow", function () {
                                $("#tabDoc").remove();

                                iv = setInterval(slowScroll, 10);
                            });
                        };

                    t.closest("ul").find("> li").removeClass("active");

                    t.parent().addClass("active");

                    if (!$("#tabDoc").length) {
                        show();
                    } else {
                        hide();
                    }

                    t.blur();
                });
            }
        },

        kittens: {
            init : function () {
                if ((/(\?|\&)kitteh=1/g).test(document.location.search)) {

                    $("img").each(function () {

                        if (!this.offsetWidth) {
                            this.style.width = "100%";
                        }

                        var w = this.offsetWidth,
                            h = this.offsetHeight,
                            rndm = (Math.random() * 10),
                            g = (Math.ceil(rndm) > 5) ? "g/" : "";

                        this.src = "http://placekitten.com/" + g + w + "/" + h;

                    });
                }
            }
        },

        table: {

            foldGroup: {
                init : function () {

                    $("span.moreStat").each(function () {
                        var that = this,
                            ih = that.innerHTML;

                        //that.innerHTML = "<span>" + ih + "</span>";
						that.innerHTML = "<span> <!-- --> </span>";
                    });

                    $("th span.moreStat").parent().prepend($.create({
                        tagName: "a",
                        href: "/",
                        className: "moreStat"
                    })).find("a").click(function (e) {
                        e.preventDefault();

                        var t = $(this),
                            group = t.closest("tbody").next("tbody.group");

                        group.toggle();

                        if (group.css("display") === "none") {
                            //t.find("span.moreStat").text("+");

                            group.replaceClass("active", "inActive");
                            t.closest("tbody").replaceClass("active", "inActive");

                        } else {

                            group.replaceClass("inActive", "active");
                            t.closest("tbody").replaceClass("inActive", "active");
                        }
                    }).find("~ span").each(function () {
                        var that = this,
                            t = $(that),
                            a = t.parent().find("a").get(0);

                        a.appendChild(that);
                    });
                }
            },

            cellAlign: {

                setAlign: function () {

                    var that = this,
                        ih = $.trim(that.innerHTML),
                        re = /^(\()?((\-|\d+)(\s[%\/](\s(\-|\d+))?)?|\-|[\w\u00C4\u00C5\u00D6]+(\s[\w\u00C4\u00C5\u00D6]+)?)(\))?$/i,
                        align = ((re).test(ih) || $(that).find("> span.sun").length) ? "center" : "";

                    if (align) {
                        that.style.textAlign = align;
                    }
                },

                init : function () {
                    $(".compareList table td").each(view.table.cellAlign.setAlign);
                }
            },

            width: {
                init : function () {
                    $(".compare table").each(function () {
                        var that = this,
                            t = $(that),
                            ths = t.find("> thead > tr > th"),
                            cols = t.find("tr:first-child > th, > tr:first-child > td"),
                            width = (100 / ths.length);

                        cols.css("width", width + "%");

                    });
                }
            }
        },

        readMore : {
            
            addNext : function (readMoreDiv, next) {

                var nextNext = next.next(),
                    readMoreDiv_JQ = $(readMoreDiv);
                
                if (next.length && next[0].tagName !== "H2") {
                    readMoreDiv_JQ.append(next);

                    if (nextNext.length && (nextNext[0].tagName !== "H2")) {
                        view.readMore.addNext(readMoreDiv, nextNext);
                    } else {
                        $(readMoreDiv).after($.create({
                            tagName : "p",
                            append : {
                                tagName : "a",
                                href : "/",
                                innerHTML : "L\u00e4s mer...",
                                data : {
                                    "isHidden" : true
                                },
                                click : function click(e) {
                                    e.preventDefault();

                                    var that = this,
                                        t = $(that);

                                    readMoreDiv_JQ.toggle("slow", function () {
                                        if (t.data("isHidden")) {
                                            t.data("isHidden", false);
                                            t.text("L\u00e4s mindre...");
                                        } else {
                                            t.data("isHidden", true);
                                            t.text("L\u00e4s mer...");
                                        }
                                    });
                                }
                            }
                        }));
                    }
                }

            },

            init : function (selector) {

                var sel = selector || ".article h2 + p";
                
                $(sel).normalize().each(function () {
                    
                    var that = this,
                        t = $(that),
                        newId = $.uniqueId("readMore_"),
                        readMoreDiv = $.create({
                            id : newId,
                            className : "readMore"
                        });

                    t.after(readMoreDiv);

                    view.readMore.addNext(readMoreDiv, t.next().next());

                });

            }
        },

        init : {
            checkImagesReady: function () {

                var imgs = $("img"),
                    imgLength = imgs.length,
                    loadedImg = 0;

                imgs.each(function () {

                    var that = this,
                        replaceImg = $.create({
                            tagName: "img",
                            alt: that.alt ? that.alt : "",
                            title: that.title ? that.title : "",
                            src: that.src,
                            load: function () {

                                loadedImg += 1;

                                if (loadedImg === imgLength) {
                                    imagesReady = true;
                                }
                            }
                        });

                    that.parentNode.replaceChild(replaceImg, that);

                });
            },

            /**
            * Make links with rel attribute set to "external" and/or "popup" open in a new window/tab
            */
            relExternal: function relExternal() {

                $("body").delegate("a, area", "click", function (e) {
                    var that = this,
                        rel = that.rel,
                        re = /(^|\s)(external|popup)(\s|$)/i;

                    if (rel && (re).test(rel)) {
                        if (e) {
                            e.preventDefault();
                        }
                        window.open(that.href);
                    }
                });
            },

            ie78: {
                
                first : true,

                ie7Init : {

                    sortby: function () {

                        var prev = null,
                            firstTop = 0,
                            height = 0,
                            lis = $("div.sortby > div > ul > li");

                        lis.each(function () {

                            var that = this,
                                t = $(that),
                                ieAdd = 8;

                            if (that.offsetHeight >= height) {
                                height = that.offsetHeight;
                            }

                            if (prev) {

                                if (!firstTop) {
                                    firstTop = parseInt(that.offsetTop + ieAdd, 10);
                                }

                                t.css({
                                    position: "absolute",
                                    top: 0,
                                    left: parseInt(prev.offsetLeft + that.offsetWidth, 10) + "px"
                                });
                            }

                            prev = that;

                        });

                        view.init.ie78.first = false;

                        lis.each(function () {

                            var that = this,
                                t = $(that),
                                morePadding = function morePadding() {

                                    var pt = parseInt(t.css("padding-top"), 10) ? parseInt(t.css("padding-top"), 10) : 0,
                                        pb = parseInt(t.css("padding-bottom"), 10) ? parseInt(t.css("padding-bottom"), 10) : 0;

                                    t.css({
                                        "padding-top": parseInt(pt + 1, 10) + "px",
                                        "padding-bottom": parseInt(pb + 1, 10) + "px"
                                    });

                                    if (that.offsetHeight < height) {
                                        morePadding();
                                    }
                                };

                            if (that.offsetHeight < height) {
                                morePadding();

                                if (that.offsetHeight > height) {
                                    t.css("padding-bottom", function () {
                                        var pb = parseInt(t.css("padding-bottom"), 10) ? parseInt(t.css("padding-bottom"), 10) : 0;

                                        return (pb - 1) + "px";
                                    });
                                }
                            }

                        });
                    }

                },

                ie78Init : {
                    labelClick: function labelClick() {
                        $("body.ie7, body.ie8").find(".sortby li").delegate("label", "click", function () {
                            var that = this,
                                t = $(that),
                                input = t.find("input").length ? t.find("input") : (function () {
                                    return $("#" + that.htmlFor);
                                }());

                            input.click();
                        });
                    }
                },

                init : function () {
                    var that = this;

                    if ($.isIE7) {
                        $.runAll.apply(that, ["ie7Init"]);
                    }

                    if ($.isIE7 || $.isIE8) {
                        $.runAll.apply(that, ["ie78Init"]);
                    }
                }

            },

            zzzzz: function () {// best methodname EVER! (has no relevance to what it actually does).
                $.runWhenExists(function () {
                    return boxHeight || ((/Safari/).test(ua) && !(/Chrome/).test(ua));
                }, function () {
                    $("body").addClass("ready");
                }, 10, 0);
            },

            styleStuff: function () {
                $("span").each(function () {

                    var that = this;

                    if (that.style.fontFamily) {
                        that.style.fontFamily = "";
                    }

                    if (that.style.color) {
                        that.style.color = "";
                    }

                    if (that.style.fontSize) {
                        that.style.fontSize = "";
                    }

                });
            }
        }
    };

    /**
    * Handle Ajax request against ClientScriptService
    * @class
    */
    model = {
        /**
        * Handles the response from jQuery ajax object
        * @param {Array} data	JSON data loaded from server.
        * @param {String} queued	ID of current queue, cloud also be bool False it no queue is used.
        */
        handleResponse: function (data, queueId) {
            if (data.d.ResponseStatus !== 200) {
                this.handleError(data.d.ResponseMessage);
                return false;
            }

            if (!queueId && this.queue.tmpCallback) {
                this.queue.tmpCallback(data.d.ResponseData[0].Value);
            } else if (queueId) {
                var i = 0,
                    l = data.d.ResponseData.length,
					x;

                for (x in this.queue[queueId]) {
                    if (this.queue[queueId][x]) {
                        for (i = 0; i < l; i += 1) {
                            if (data.d.ResponseData[i].CommandName.toLowerCase() === x.toLowerCase() && this.queue[queueId][x].callback) {
                                this.queue[queueId][x].callback(data.d.ResponseData[i].Value);
                            }
                        }
                    }
                }

                model.resetQueue(queueId);
            }
        },
        /**
        * Holds queue objects. Each queue should have a unique name and contains properties with correspondant names of the name of webservice to be called.
        * Value of "WebServiceMethod" should always be false
        * @example queue1 : { WebServiceMethod : false }
        * @property
        */
        queue: {
            queue1: {
                GetTwitter: false,
                GetFriends: false
            },

            queue2: {
                AddAccount: false,
                AddSubscriber: false
            }
        },
        /**
        * Add new Queue Item to que based on queueId. If que is full. Trigger the JSON request. ie. 
        * @example model.addToQueue('que1', ['AddStuff', { name: 'stuff' }], view.removeStuff)
        * 
        * @param {String} queueId	ID of current queue, cloud also be bool False it no queue is used.
        * @param {Array} payload	Array containg Webservie name and arguments ie. ['DoStuff',  { name : 'lorem ipsum' }]
        * @param {Function} callback	Callback method, can be false if no callback is requierd 
        */
        addToQueue: function (queueId, payload, callback) {
            var queuePayload,
				i,
				queueObj = { Name: payload[0], Params: [] };

            for (i in payload[1]) {
                if (i in payload[1]) {
                    queueObj.Params.push({ Name: i, Value: payload[1][i] });
                }
            }

            if (!queueId) {
                this.queue.tmpCallback = callback;

                this.addToAjaxQueue({ request: { Commands: [queueObj]} }, false);
                return;
            } else if (this.queue[queueId][payload[0]]) {
                return false;
            }

            if (typeof this.queue[queueId] === 'undefined' || typeof this.queue[queueId][payload[0]] === 'undefined') {
                this.handleError('No queueId with the name ' + queueId + ' or the queItem ' + payload[0] + ' is not in the queue ' + queueId);
            }

            this.queue[queueId][payload[0]] = {};
            this.queue[queueId][payload[0]].payload = queueObj;
            this.queue[queueId][payload[0]].callback = callback;

            if (this.isQueueReady(queueId)) {
                queuePayload = this.getQueuePayload(queueId);
                this.addToAjaxQueue(queuePayload, queueId);
            }
        },
        /**
        * Check if queue is ready to be triggered.
        * @param {String} queueId	ID of current queue.
        * @return {Boolean}	Returns true if queue is ready.
        */
        isQueueReady: function (queueId) {
            var isReady = true,
				i;

            for (i in this.queue[queueId]) {
                if (!this.queue[queueId][i]) {
                    isReady = false;
                    break;
                }
            }

            return isReady;
        },
        /**
        * Get current queues payload as and Array.
        * @param {String} queueId	ID of current queue.
        * @return {Array}	Payload array with main webservice methods as first argument.
        */
        getQueuePayload: function (queueId) {
            var payloadArray = [],
				i;

            for (i in this.queue[queueId]) {
                if (this.queue[queueId][i]) {
                    payloadArray.push(this.queue[queueId][i].payload);
                }
            }

            return { request: { Commands: payloadArray} };
        },
        /**
        * Resets the queue of current queueId.
        * @param {String} queueId	ID of current queue.
        */
        resetQueue: function (queueId) {
            var i;
            for (i in this.queue[queueId]) {
                if (this.queue[queueId][i]) {
                    this.queue[queueId][i] = false;
                }
            }
        },
        /**
        * Setup ajax properties for new ajax request.
        * @param {Array} payload	Array to be posted to webservice.
        * @param {String} queueId	ID of current queue.
        */
        addToAjaxQueue: function (payload, queueId) {
            var ajaxOptions = {
                url: '/ScriptServices/ClientDataTransferService.asmx/GetData',
                type: 'post',
                dataType: 'json',
                contentType: 'application/json',
                data: JSON.stringify(payload),
                callback: queueId,
                success: function (data) {
                    var arg = [data, this.callback];
                    model.handleResponse.apply(model, arg);
                },
                error: model.handleError
            };

            this.doJsonPost(ajaxOptions);
        },
        /**
        * Array to hold currently running ajax requests
        * @property
        */
        ajaxQueue: [],

        /**
        * Triggers jQuery's ajax method and triggers handleResponse method passing loaded data and queId.
        * Uses this.ajaxQueue queue to keep ajax request to be invoked in proper order.
        * @param {Object} ajaxOptions Object containing properties of ajax request.
        */
        doJsonPost: function (ajaxOptions) {
            var ajaxQueueItem,
                ajaxCall = (function (ajaxOptions, obj) { //Return anonymouse function to keep context of ajaxOpotions and obj.
                    return function () {
                        var onSuccess = ajaxOptions.success,
                            ajaxQueue = obj.ajaxQueue;
                        // Override succuess function in ajaxOptions to add logic for handling ajaxQueue
                        ajaxOptions.success = function () {
                            if (onSuccess) {
                                onSuccess.apply(obj, arguments);
                            }

                            ajaxQueue.shift();

                            if (ajaxQueue.length > 0) {
                                ajaxQueueItem = obj.ajaxQueue[0];
                                ajaxQueueItem();
                            }
                        };
                        $.ajax(ajaxOptions);
                    };
                } (ajaxOptions, this));
            //Add new Ajax call to queue
            this.ajaxQueue.push(ajaxCall);
            //If ajax queue is empty or contain only a singel call, invoke it.
            if (this.ajaxQueue.length <= 1) {
                ajaxQueueItem = this.ajaxQueue[0];
                ajaxQueueItem();
            }
        },
        /**
        * Throws error from jQuery ajax method.
        */
        handleError: function (err) {
            throw new Error(err);
        }
    };

    $(document).ready(function () {
        $.runInit(view);
    });

}(window));

