/*
 * Magico Software Javascript Code Library
 *
 * Copyright (c) 2011 Magico Software
 * Author: Martin Poucher
 * Company: Magico Software
 *
 * Version: 1.0
 * Created: 1st December 2011
 * Last Modified: 12th January 2012
 */

/* Creating the magico namespace */
var magico = {};

(function (magico) {
    magico.utilities = {
        countEvents: function (element, eventName) {
            var eventsCount = 0;
                    
            $.each($(element).data("events"), function (i, ev) {
                if (magico.utilities.isNullOrEmpty(eventName) || i === eventName) {
                    eventsCount++;
                }
            });

            return eventsCount;
        },
    
        isFunction: function (func) {
            return typeof func === "function";
        },
        
        isNullOrEmpty: function (obj) {
            return (obj === null || obj === "" || obj === undefined || (obj instanceof Array && obj.length === 0));
        },
        
        getInt: function (number, defaultNumber) {
            var returnNumber = defaultNumber;
            if (magico.utilities.isNullOrEmpty(number) === false) {
                returnNumber = parseInt(number, 10);
            }
            
            return returnNumber;
        },
        
        getVal: function (obj) {
            return (this.isNullOrEmpty(obj) === false && typeof $(obj).val() !== "undefined" ? $(obj).val() : "");
        },
        
        getImageDimensions: function (imgLink) {
            var tempImg = $("<img />").attr("src", imgLink).hide(),
                imgHeight = 0,
                imgWidth = 0;
                
            $("body").append(tempImg);
            imgHeight = tempImg.height();
            imgWidth = tempImg.width();
            $(tempImg).remove();
            
            return {
                height: imgHeight,
                width: imgWidth
            };
        },
        
        padString: function (str, charNum, padChar, isPadLeft) {
            var paddedString = str + "";
            if (magico.utilities.isNullOrEmpty(isPadLeft) && typeof isPadLeft !== "bool") {
                isPadLeft = true;
            }
            
            if (magico.utilities.isNullOrEmpty(str) === false &&
                isNaN(charNum) === false &&
                magico.utilities.isNullOrEmpty(padChar) === false &&
                paddedString.length < charNum) {
                while(paddedString.length < charNum) {
                    if (isPadLeft) {
                        paddedString = padChar + paddedString;
                    } else {
                        paddedString = paddedString + padChar;
                    }
                }
            }
            
            return paddedString
        },
        
        preloadElement: function (elementToLoad, callback, onErrorFunc) {
            $(elementToLoad).load(function () {
                $(this).unbind("load");
                if (magico.utilities.isFunction(callback)) {
                    callback.call(this, elementToLoad);
                }                
            }).error(function () {
                $(this).unbind("error");
                onErrorFunc.call(this);
            });
        },
        
        preloadImage: function (imageToLoad, callback, onErrorFunc) {
            var preloadImg = new Image();
            
            if (magico.utilities.isFunction(callback)) {
                preloadImg.onerror = function() {
                    preloadImg.onerror = function () {};
                    onErrorFunc();
                };
                preloadImg.onload = function () {
                    preloadImg.onload = function () {};
                    callback.call(this, imageToLoad);
                };                               
            }
            
            preloadImg.src = imageToLoad;
        },
        
        removeCursorWaiting: function () {
            $(this).css("cursor", "");
            $("body").css("cursor", "");
            return this;
        },
        
        roundNumber: function (num, decimalPlaces) {
            if (magico.utilities.isNullOrEmpty(num)) { return null; }
            else if (isNaN(num)) { return "0.00"; }
            
            var dec = magico.utilities.getInt(decimalPlaces, 2),
                res = String(Math.floor(num * Math.pow(10, dec)) / Math.pow(10, dec)),
                isNegative = num < 0,
                arrNum,
                frmtNum = "";
                
            if (res.indexOf(".") == -1) {
                res += ".00";
            } else {
                res = res + "";
            }

            while (res.length - res.indexOf('.') <= dec) {
                res += "0";
            }
            
            if (isNegative) {
                res = res.substring(1, res.length);
            }

            /* Formatting the number to include commas where necessary */
            arrNum = res.split(".");
            for (var i = 0; i < arrNum.length; i++) {
                if (i === 0 && arrNum[i].length > 3) {
                    for (var j = arrNum[i].length - 1; j >= 0; j--) {
                        frmtNum = ((arrNum[i].length - 1 - j) % 3 == 2 ? "," : "") + arrNum[i].split("")[j] + frmtNum;
                    }
                }
                else {
                    frmtNum += (i == 1 ? "." : "") + arrNum[i];
                }
            }
            
            return (isNegative ? "-" : "") + frmtNum;
        },
        
        setCursorWaiting: function () {
            $(this).css("cursor", "wait");
            $("body").css("cursor", "wait");
            return this;
        },
        
        writeToConsole: function (msg) {
            var currentDate = new Date(),
                currentMilliseconds = magico.utilities.padString(currentDate.getUTCMilliseconds(), 3, "0");
                
            if (!window.console) { console = {}; }
            console.log = console.log || function(){};
            console.warn = console.warn || function(){};
            console.error = console.error || function(){};
            console.info = console.info || function(){};

            console.log(currentDate.toLocaleTimeString() + "." + currentMilliseconds + ": " + msg);
        }
    };
    
    magico.validation = {
        emailRegEx: /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/,
        
        isValidEmail: function (email) {
            return (magico.validation.emailRegEx.test(email) === true && email !== "");
        }
    };
    
    magico.keyboard = { 
        isEnter: function (keyEvent) {
            return (this.keyPressed(keyEvent) === 13);
        },
        
        isEscape: function (keyEvent) {
            return (this.keyPressed(keyEvent) === 27);
        },
    
        isLeftArrow: function (keyEvent) {
            return (this.keyPressed(keyEvent) === 37);
        },
      
        isRightArrow: function (keyEvent) {
            return (this.keyPressed(keyEvent) === 39);
        },
        
        keyPressed: function (keyEvent) {
            return keyEvent.keyCode || keyEvent.which;
        }
    };
    
    $.fn.reverse = [].reverse;
    
    Array.prototype.remove = function(from, to) {
        var rest = this.slice((to || from) + 1 || this.length);
        this.length = from < 0 ? this.length + from : from;
        return this.push.apply(this, rest);
    };   
    
    if (!Array.prototype.indexOf) {
        Array.prototype.indexOf = function(obj, start) {
             for (var i = (start || 0), j = this.length; i < j; i++) {
                 if (this[i] === obj) { return i; }
             }
             return -1;
        }
    }
     
    magico.animation = {
        attrDefaultColour: "data-color",
        
        backgroundHighlight: function (element, colour, speed) {
            var beforeColour;
            
            if (magico.utilities.isNullOrEmpty($(element).attr(this.attrDefaultColour))) {
                beforeColour = $(element).css("backgroundColor");
                $(element).attr(this.attrDefaultColour, beforeColour);
            } else {
                beforeColour = $(element).attr(this.attrDefaultColour);
            }
            
            $(element).animate({backgroundColor: colour}, speed, function () {
                $(element).animate({backgroundColor: beforeColour}, speed);
            });
            
            return element;           
        }
    };    
    
    magico.ajax = {
        isLocked: false
    };
    
    magico.ajax.data = function () {
        this.request = {};
    };    
    
    magico.ajax.request = function (options) {
        var settings = {
                url: "",
                data: "",
                dataType: "json",
                type: "POST",
                contentType: "application/json; charset=utf-8",
                presend: function () { },
                success: function () { },
                error: function () { }
            },
            send;
            
        $.extend(settings, options);
            
        if (magico.ajax.isLocked === false && 
            magico.utilities.isNullOrEmpty(settings.url) === false && 
            magico.utilities.isNullOrEmpty(settings.data) === false) {
            magico.ajax.isLocked = true;
            
            settings.presend();
            
            $.ajax({
                url: settings.url,
                data: JSON.stringify(settings.data),
                dataType: settings.dataType,
                type: settings.type,
                contentType: settings.contentType,
                success: function (response) {
                    settings.success(response);                        
                    magico.ajax.isLocked = false;
                },
                error: function (respXhr, respStatus, respError) {
                    settings.error(respXhr, respStatus, respError);
                    magico.ajax.isLocked = false;
                }
            });
        }
        
        return this;
    };

    magico.dimensions = function (jq) {
        this.selector = jq;
        return this;
    };
    
    magico.dimensions.prototype = {
        clean: function (el) { 
            el = el.replace("px", "");
            
            if (el !== "" && typeof el !== "undefined" && isNaN(parseFloat(el)) === false) {
                el = parseFloat(el); 
            } else { 
                el = 0; 
            }
            
            return el;  
        },
        
        top: function () { 
            if ($(this.selector) !== null) { 
                var tempOffset = $(this.selector).offset();
                if (tempOffset !== null && typeof tempOffset.top !== "undefined") {
                    return tempOffset.top;
                }
            }
            return 0;
        }, 
        
        positionTop: function () {
            if ($(this.selector) !== null) { 
                var tempOffset = $(this.selector).position();
                if (tempOffset !== null && typeof tempOffset.top !== "undefined") {
                    return tempOffset.top;
                }
            }
            return 0;
        },
        
        left: function () {
            if ($(this.selector) !== null) { 
                var tempOffset = $(this.selector).offset();
                if (tempOffset !== null && typeof tempOffset.left !== "undefined") {
                    return tempOffset.left;
                }
            }            
            return 0;
        }, 
        
        positionLeft: function () {
            if ($(this.selector) !== null) { 
                var tempOffset = $(this.selector).position();
                if (tempOffset !== null && typeof tempOffset.left !== "undefined") {
                    return tempOffset.left;
                }
            }            
            return 0;
        }, 
        
        height: function () {
            if ($(this.selector) !== null) { 
                return $(this.selector).height();
            }            
            return 0;
        }, 
        
        width: function () {
            if ($(this.selector) !== null) { 
                return $(this.selector).width();
            }            
            return 0;
        }, 
        
        paddingTop: function () { 
            return this.clean($(this.selector).css("padding-top"));
        },
        
        paddingBottom: function () { 
            return this.clean($(this.selector).css("padding-bottom")); 
        },
        
        paddingLeft: function () { 
            return this.clean($(this.selector).css("padding-left")); 
        },
        
        paddingRight: function () { 
            return this.clean($(this.selector).css("padding-right")); 
        },
        
        marginTop: function () { 
            return this.clean($(this.selector).css("margin-top")); 
        },
        
        marginBottom: function () { 
            return this.clean($(this.selector).css("margin-bottom")); 
        },
        
        marginLeft: function () { 
            return this.clean($(this.selector).css("margin-left")); 
        },
        
        marginRight: function () { 
            return this.clean($(this.selector).css("margin-right")); 
        },
        
        borderTop: function () { 
            return this.clean($(this.selector).css("border-top-width")); 
        },
        
        borderBottom: function () { 
            return this.clean($(this.selector).css("border-bottom-width")); 
        },
        
        borderLeft: function () { 
            return this.clean($(this.selector).css("border-left-width")); 
        },
        
        borderRight: function () { 
            return this.clean($(this.selector).css("border-right-width")); 
        },
        
        scrollTop: function () {
            return $(this.selector).scrollTop();
        },
        
        getHeight: function () { 
            return this.height() + 
                   this.paddingTop() + 
                   this.paddingBottom() + 
                   this.marginTop() + 
                   this.marginBottom() + 
                   this.borderTop() + 
                   this.borderBottom(); 
        },
        
        getWidth: function () { 
            return this.width() + 
                   this.paddingRight() + 
                   this.paddingLeft() + 
                   this.marginLeft() + 
                   this.marginRight() + 
                   this.borderLeft() + 
                   this.borderRight(); 
        },
        
        getBorderToBorderHeight: function () { 
            return this.height() + 
                   this.paddingTop() + 
                   this.paddingBottom() + 
                   this.borderTop() + 
                   this.borderBottom(); 
        },
        
        getBorderToBorderWidth: function () { 
            return this.width() + 
                   this.paddingRight() + 
                   this.paddingLeft() + 
                   this.borderLeft() + 
                   this.borderRight(); 
        },
        
        getWidthRight: function () { 
            return this.paddingRight() + 
                   this.marginRight() + 
                   this.borderRight(); 
        },
        
        getExtraHeights: function () { 
            return this.paddingTop() + 
                   this.marginTop() + 
                   this.borderTop() + 
                   this.paddingBottom() + 
                   this.marginBottom() + 
                   this.borderBottom(); 
        },
        
        getExtraWidths: function () { 
            return this.paddingLeft() + 
                   this.marginLeft() + 
                   this.borderLeft() + 
                   this.paddingRight() + 
                   this.marginRight() + 
                   this.borderRight(); 
        },
        
        getBorderAndPaddingHeights: function () { 
            return this.paddingTop() + 
                   this.paddingBottom() + 
                   this.borderTop() + 
                   this.borderBottom(); 
        },
        
        getBorderAndPaddingWidths: function () { 
            return this.paddingLeft() + 
                   this.paddingRight() + 
                   this.borderLeft() + 
                   this.borderRight(); 
        }
    }; 
}(magico));

/* jQuery plugin that makes sure only 1 event is bound to the selected element */
/* Requires: magico.utilities */
(function ($) {
    $.fn.bindOnce = function (eventName, functionToBind, overrideAttached) {
        return this.each(function() {
            if (typeof overrideAttached === "undefined") {
                overrideAttached = true;
            }
            
            if (typeof functionToBind === "undefined") {
                functionToBind = function () {};
            }
        
            if (magico.utilities.isNullOrEmpty(eventName) == false) {
                if (overrideAttached) {
                    $(this).unbind(eventName).bind(eventName, functionToBind);
                } else {
                    if (magico.utilities.countEvents(this, eventName) === 0) {
                        $(this).bind(eventName, functionToBind);
                    }
                }
            }
        });
    };
}(jQuery));

/* Plugin to slide up a table row */
/* Requires: magico.utilities */
(function ($) {
    $.fn.slideUpRow = function (speed, callback) {
        var defaultSpeed = 500;
            
        function initHideRow(tableRow) {
            return tableRow.find("td").wrapInner("<div style='border:0;margin:0;padding:0;overflow:hidden'/>");
        }
        
        return this.each(function () {
            if ($(this).is(":visible")) {
                if (typeof speed === "undefined") {
                    speed = defaultSpeed;
                }
                
                var $thisRow = $(this),
                    $divvedCells = initHideRow($thisRow),
                    $cellDivs = $divvedCells.children("div"),
                    splitSpeed = (speed / 2);
                
                $cellDivs.animate({
                    "opacity": 0
                }, splitSpeed, function () {
                    var cellDim = new magico.dimensions($(this).parent()),
                        cellPaddingTop = cellDim.paddingTop(),
                        cellPaddingBottom = cellDim.paddingTop();
                    
                    $(this).css({                        
                        "padding-top": cellPaddingTop + "px",
                        "padding-bottom": cellPaddingBottom + "px"
                    });
                    
                    $(this).parent().css({
                        "padding-top": "0px",
                        "padding-bottom": "0px"
                    });
                    
                    $(this).animate({
                        "height": 0,
                        "padding-top": 0,
                        "padding-bottom": 0
                    }, splitSpeed, function () {
                        $(this).parent().parent().hide();
                    
                        $(this).parent().css({                        
                            "padding-top": cellPaddingTop + "px",
                            "padding-bottom": cellPaddingBottom + "px"
                        });
                        
                        if ($cellDivs.index(this) === ($cellDivs.length - 1)) {
                            $(this).parents("tr").hide().children("td").show();
                            
                            if (typeof callback  === "function") { 
                                callback.call(this);
                            }
                        }
                        
                        var cnt = $(this).contents();
                        $(this).replaceWith(cnt);
                    });
                });
            } else {
                callback.call(this);
            }
        });
    };
}(jQuery));

(function ($) {     
    /* Plugin to slide down a hidden table row */
    $.fn.slideDownRow = function (speed, callback) {
        var padTop = 0,
            padBottom = 0,
            defaultSpeed = 500,
            methods = {
                maxHeight: function (tableCells) {
                    var maxH = 0;
                    tableCells.each(function (i, n) {
                        if ($(n).height() > maxH) {
                            maxH = $(n).height();
                        }
                    });
                    
                    return maxH;
                }
            };
            
        function initShowRow(tableRow) {
            var cells = tableRow.find("td"),
                dim;
        
            if (cells.length > 0) {
                dim = new magico.dimensions(cells[0]);
                padTop = dim.paddingTop();
                padBottom = dim.paddingBottom();
            }
            
            return tableRow.find("td").css({"padding": 0, "opacity": 0}).wrapInner("<div style='border:0;margin:0;padding:0'/>");
        }
        
        return this.each(function () {
            if ($(this).is(":hidden")) {
                if (typeof speed === "undefined") {
                    speed = defaultSpeed;
                }
                
                var $thisRow = $(this),
                    $thisRowCells = $thisRow.children("td"),
                    $divvedCells = initShowRow($thisRow),
                    $cellDivs = $divvedCells.children("div"),
                    splitSpeed = (speed / 2),
                    height;
                
                $thisRow.show();
                height = methods.maxHeight($cellDivs) + padTop + padBottom;
                $cellDivs.css("height", "0px");
                
                $cellDivs.animate({
                    "height": height + "px"
                }, splitSpeed, function () {
                    var $thisCell = $(this).parent(),
                        cnt;
                        
                    $(this).parent().animate({
                        "opacity": 1
                    }, splitSpeed, function () {
                        if ($thisRowCells.index($thisCell) === ($thisRowCells.length - 1)) {
                            if (typeof callback === "function") { 
                                callback.call(this);
                            }
                        }
                    });

                    /* Restoring cell to original state */
                    $thisCell.css({
                        "padding-top": padTop + "px",
                        "padding-bottom": padBottom + "px"
                    });
                    
                    $(this).css({
                        "padding-top": "0px",
                        "padding-bottom": "0px"
                    });
                    
                    cnt = $(this).contents();
                    $(this).replaceWith(cnt);            
                });
            }
        });
    };      
}(jQuery));

(function ($) {
    /* Sticky element plugin */
    $.fn.stickyBox = function (options) {
        var settings = $.extend({
                "fixDimensions": false
            }, options),
            stickyWrapID = "magiwrap",
            $this = this,
            stickyDimensions = new magico.dimensions($this);
        
        if ($this !== null && $this.length > 0) {
            $(window).scroll(function () {
                /* Check if the box should be pinned */        
                if ($this.parent().offset().top < $(window).scrollTop()) {
                    $this.css({
                        "position": "fixed",
                        "left": $this.parent().offset().left,
                        "top": 0
                    });
                } else {
                    $this.css({ "position": "inherit" });                
                }
            });
        }
                    
        return this.each(function () {
            var sHeight = "height:" + stickyDimensions.getHeight() + "px;",
                sWidth = "width:" + stickyDimensions.getWidth() + "px;",
                fixedDim = (settings.fixDimensions ? sHeight + sWidth : "");
                
            $this.wrap("<div class='" + stickyWrapID + "' style='overflow:hidden;" + fixedDim + "' />");                        
        });
    };
}(jQuery));

(function ($) {    
    /* Plugin to display a popup modal */
    $.fn.magiPopup = function (options) {
        var settings = $.extend({
            animationSpeed: 500,
            isModal: true,
            modalId: "magimodal",
            modalOpacity: 0.8,
            popupWidthPercentage: 50,
            popupCloseSelector: "",
            onClose: function () { },
            success: function () { }
        }, options);
        
        function windowDimensions() {
            var windowDim = {
                documentHeight: $(document).height(),
                documentWidth: $(document).width(),
                windowHeight: $(window).height()
            };
            
            return windowDim;
        }
        
        function getModalStyles() {
            var dims = windowDimensions();
                
            return {
                "opacity": 0,
                "position": "absolute",
                "top": 0,
                "left": 0,
                "height": dims.documentHeight + "px",
                "width": dims.documentWidth + "px",
                "background-color": "#000",
                "z-index": 100
            };
        }
        
        function getPopupStyles(popup) {
            var dims = windowDimensions(),
                popupDims = new magico.dimensions(popup);
                
            $(popup).css("width", "50%");
                
            return {
                "position": "fixed",
                "top": ((dims.windowHeight / 2) - (popupDims.getHeight() / 2)),
                "left": ((dims.documentWidth / 2) - (popupDims.getWidth() / 2)),
                "z-index": 200
            };
        }
        
        function resetModalAndPopup(popup) {
            $(popup).hide();
            $("#" + settings.modalId).hide();
        }
        
        function hideModal() {
            $("#" + settings.modalId).fadeOut(settings.animationSpeed);
        }
        
        function hidePopup(popup) {
            $(popup).fadeOut(settings.animationSpeed, function() {
                settings.onClose.call(this);
            });
        }
        
        function hideAll(popup) {
            hidePopup(popup);
            hideModal();
        }
        
        function attachModalCloseListeners(popup) {
            $("body").bindOnce("keypress", function (ev) {
                if (magico.keyboard.isEscape(ev)) {
                    hideAll(popup);
                }       
            });
            
            $("#" + settings.modalId).unbind("mouseup").bind("mouseup", function () {
                hideAll(popup);
            });
        }
        
        function attachPopupCloseListeners(popup) {
            $(settings.popupCloseSelector).unbind("click").bind("click", function () {
                hideAll(popup);
                return false;
            });
        }
        
        function showPopup() {
            if (this.length !== 0) {
                attachPopupCloseListeners(this);
                
                $(this).css(getPopupStyles(this));
                
                $(this).fadeIn(settings.animationSpeed, function () {
                    if (magico.utilities.isFunction(settings.success)) {
                        settings.success();
                    }
                });
            }
        }
        
        function showModal(popup) {
            resetModalAndPopup(popup);
            
            if (settings.isModal) {
                var modalElement = $("#" + settings.modalId);
                
                if (modalElement.length === 0) {
                    modalElement = $("<div />").attr("id", settings.modalId).attr("style", getModalStyles());
                    $("body").append(modalElement);
                }
                
                modalElement.css(getModalStyles());
                attachModalCloseListeners(popup);
                
                modalElement.show().animate({
                    "opacity": settings.modalOpacity
                }, settings.animationSpeed, function () {
                    showPopup.call(popup);
                });
            }
        }
        
        return this.each(function () {
            showModal(this);
        });                       
    };    
}(jQuery));  

(function ($){
    /* Carousel plugin */
	$.fn.magiCarousel = function (options) {
	    var settings = $.extend({
	            activeClassName: "active",
	            animationSpeed: 1000,
	            effect: "Random",
	            enableDebug: false,
	            enableDesignerMode: false,
	            enableTestMode: false,
	            loadingImage: "/img/loading.gif",
	            loadingImageClass: "loadingImages",
	            onImageChange: function () { },
	            randomEffects: ["FadeBox", "FadeBoxDownRight", "FadeBoxUpLeft", "FadeBoxDown", "FadeBoxUp", "FadeBoxRight", 
                                "FadeBoxLeft", "FadeBoxRandom", "SliceDownRight", "SliceDownLeft", "SliceDown", "SliceUp",
                                "SliceRight", "SliceLeft"],
	            selectorNavigationLink: "ul#m_galleryNav li a",
	            selectorNextButton: "a.next",
	            selectorPrevButton: "a.prev",
	            timeBetweenAnimations: 5000   
	        }, options);
	        
	    var magiCarouselManager = function (carousel) {	
	        var boxColumns = 8,
                boxRows = 5,
                classForBoxes = "magibox",
                classForSlices = "magislice",
                classForSliderBoxes = "magislider-box",
	            displayImage = function () {},        
                effectForNextAnimation = settings.effect,
                firstImageHeight = 0,
                firstImageWidth = 0,
                htmlSetup = function () {},
                idForSlider = "magislider",
                initialCssProps = null,
                isAnimationRunning = false,
                isTimerPaused = false,
                isTimerRunning = false,
                isTimerStopped = false,
                isRandom = false,
                nextImageIndex = 0,
                thisCarousel = this,
                timerBetweenAnimation = null,
                totalImages = 0,
                totalHeight = 0,
                totalWidth = 0,
                visibleImageIndex = 0;

            carousel = $(carousel);            
            
            /* NOTE: The following functions are base functions and shouldn't be edited */
            function getImageHeight(carousel, index) {
                if (typeof index === "undefined") {
                    index = 0;
                }
                
                return $("img:eq(" + index + ")", carousel).height();
            }
            
            function getImageWidth(carousel, index) {
                if (typeof index === "undefined") {
                    index = 0;
                }
                
                return $("img:eq(" + index + ")", carousel).width();
            }
            
            function getImageSrc(carousel, index) {
                if (typeof index === "undefined") {
                    index = 0;
                }
                
                return $("img:eq(" + index + ")", carousel).attr("src");
            }
            
            function getNextImageIndex() {
                return (visibleImageIndex + 1 >= totalImages ? 0 : visibleImageIndex + 1);
            }

            function getPreviousImageIndex() {
                return (visibleImageIndex - 1 < 0 ? totalImages - 1 : visibleImageIndex - 1);
            }

            function initialiseBase(carousel) {    
                $(carousel).children().show();        
                totalImages = $(carousel).children().not("." + settings.loadingImageClass).length;
                
	            $(carousel).children().each(function (i, el) { 
	                totalHeight += $(el).height();
		            totalWidth += $(el).width(); 
		        });
		        
                visibleImageIndex = 0;
                firstImageHeight = getImageHeight(carousel);
                firstImageWidth = getImageWidth(carousel);
                
		        $(carousel).css({
		            height: firstImageHeight,
		            overflow: "hidden",
		            width: firstImageWidth
		        });
		        
                $(carousel).children().hide();
            }
    	    
	        function startAnimation(carousel) {
	            timerBetweenAnimation = setTimeout(function() { 
	                displayImage(carousel) 
	            }, settings.timeBetweenAnimations);
	            
	            isTimerStopped = false;
	            isTimerRunning = true;
	            isTimerPaused = false;
	        }
    	    
	        function stopAnimation() {
	            clearTimeout(timerBetweenAnimation);
	            isTimerStopped = true;
	            isTimerRunning = false;
	            isTimerPaused = false;
	        }
	        
	        function pauseAnimation() {
	            isTimerStopped = false;
	            isTimerRunning = false;
	            isTimerPaused = true;
	        }
	        
	        function setHoverActions(carousel) {
	            $(carousel).hover(function() {
	                stopAnimation();
	            }, function() {
	                startAnimation(carousel);
	            });
	        }
	        
	        function setKeyboardActions(carousel) {
                $(window).keypress(function (ev){
                    if (magico.keyboard.isLeftArrow(ev)) {
                        displaySpecificImage(carousel, getPreviousImageIndex());
                    } else if (magico.keyboard.isRightArrow(ev)) {
                        displaySpecificImage(carousel, getNextImageIndex());
                    }
	            });
	        }
	        
	        function setClickActions(carousel) {
	            $(settings.selectorNavigationLink, $(carousel).parent()).click(navigationLinkClicked);
	        }
	        
	        function navigationLinkClicked(ev) {
	            var linkClass = $(this).attr("class"),
	                linkHref = $(this).attr("href"),
	                nextImageIndex = (magico.utilities.isNullOrEmpty(linkHref) ? 0 : parseInt(linkHref.replace("#", ""), 10));
	            
                nextImageIndex = nextImageIndex - 1;
	            
	            if ("a." + linkClass === settings.selectorPrevButton) {
	                nextImageIndex = getPreviousImageIndex();
	            } else if ("a." + linkClass === settings.selectorNextButton) {
	                nextImageIndex = getNextImageIndex();
	            }
	            
                return displaySpecificImage(carousel, nextImageIndex);
            }
            
            function displaySpecificImage(carousel, imgIndex) {
	            if (isAnimationRunning == false && imgIndex !== visibleImageIndex) {
	                stopAnimation();
    	            
	                if (isNaN(imgIndex) === false) {
	                    htmlSetup(carousel, imgIndex);
	                    displayImage(carousel);
	                    startAnimation(carousel);
	                }
	            }
	            
	            return false;
	        }
	        
	        function setActiveImageLink(imgIndex) {
	            $(settings.selectorNavigationLink)
	            .not(settings.selectorNextButton)
	            .not(settings.selectorPrevButton)
	            .removeClass(settings.activeClassName)
	            .eq(imgIndex)
	            .addClass(settings.activeClassName);	            
	        }
    	    
	        var initialiseHtmlForSlideHorizontal = function(carousel) {
	            $(carousel).children().show().wrap("<div class='" + classForSliderBoxes + "'></div>");
	            $(carousel).wrapInner("<div id='" + idForSlider + "' />");
		        $("#" + idForSlider).css({
		            height: firstImageHeight + "px",
		            left: 0,
		            position: "absolute",
		            top: 0,
		            width: totalWidth + "px"
		        });
    		    
		        $("." + classForSliderBoxes).css({ "float": "left" });
	        };
	        
	        /* Html Generator Functions */
	        var initialiseHtml = function(carousel, rows, cols, overrideNextImageIndex) {
	            if (isRandom) {
	                var randomNum = Math.floor(Math.random() * (settings.randomEffects.length)),
	                    initialiseFunc = thisCarousel["initialise" + settings.randomEffects[randomNum]];
                
                    if (initialiseFunc instanceof Function) {
                        initialiseFunc(carousel);
                    }
                    
                    rows = boxRows;
                    cols = boxColumns;
	            } 
	            
                nextImageIndex = getNextImageIndex();
	            
	            var boxWidth = $(carousel).width() / boxColumns,
	                boxHeight = $(carousel).height() / boxRows,
	                image = getImageSrc(carousel, visibleImageIndex),
	                nextImage,
	                rowCount = 0,
	                colCount = 0,
	                initialCss = {
					    height: boxHeight + "px",
						float: "left",
						opacity: 0,
						width: boxWidth + "px"
	                };
	            
	            if (initialCssProps !== null && typeof initialCssProps !== "undefined" && initialCssProps.constructor === Object) {
	                initialCss = $.extend(initialCss, initialCssProps);
	            }
	            
	            if (overrideNextImageIndex !== null && isNaN(parseFloat(overrideNextImageIndex)) == false) {
	                nextImageIndex = overrideNextImageIndex;
	            } else {
	                carousel.css({
	                    background: "#fff url(" + image + ") no-repeat",
	                    position: "relative"
	                });
	            }
	            
	            nextImage = getImageSrc(carousel, nextImageIndex);	            
	            $("." + classForBoxes, carousel).remove();
	            
	            for (; rowCount<rows; rowCount = rowCount + 1) {
	                colCount = 0;
	                for (; colCount<cols; colCount = colCount + 1) {
	                    var xPos = (colCount * boxWidth),
	                        yPos = (rowCount * boxHeight),
	                        boxCss = $.extend({
								        background: "url('" + nextImage + "') no-repeat -" + xPos + "px -" + yPos + "px",
								        left: (boxWidth * colCount) + "px", 
								        position: "absolute",
								        top: (boxHeight * rowCount) + "px"
	                                }, initialCss);
	                
	                    carousel.append(
	                        $("<div class='" + classForBoxes + "'></div>").css(boxCss)
	                    );
	                }
	            }
	        };
	        
	        var initialiseHtmlForBoxes = function(carousel, imgToShowNext) {
	            initialiseHtml(carousel, boxRows, boxColumns, imgToShowNext);
	        };
	        
	        var initialiseHtmlForSlices = function(carousel, imgToShowNext) {
	            initialiseHtml(carousel, 1, boxColumns, imgToShowNext);
	        };
	        /* End of Html Generator Functions */
	        
	        /* Animation Functions */
	        function animateBoxes(carousel, arrayOfBoxes, animateProps, initHtmlFunc, cssProps, delay) {
	            var timeDelay = 0,
	                animationDelay = 100,
	                initialiseHtmlFunc = initialiseHtmlForBoxes,
	                cssProperties = {},
	                animationProperties = {};
	                
	            if (isTimerRunning) {
	                pauseAnimation();
	            }
	            
	            if (typeof delay !== "undefined" && isNaN(parseInt(delay, 10)) === false) {
	                animationDelay = parseInt(delay, 10);
	            }
	            
	            if (cssProps !== null && typeof cssProps !== "undefined" && cssProps.constructor === Object) {
	                cssProperties = $.extend(cssProperties, cssProps);
	            }
	            
	            if (typeof initHtmlFunc !== "undefined" && initHtmlFunc.constructor === Function) {
	                initialiseHtmlFunc = initHtmlFunc;
	            }
	            
	            if (animateProps !== null && typeof animateProps !== "undefined") {
	                animationProperties = $.extend(animationProperties, animateProps);
	            }
	            
	            $(arrayOfBoxes).each(function (i, n) {
	                $(n).each(function(j, item) {
	                    if (i >= arrayOfBoxes.length - 1 && j >= $(n).length - 1) {	                        
	                        setTimeout(function() {
	                            isAnimationRunning = true;
	                            setActiveImageLink(nextImageIndex);
	                            
	                            $(item).css(cssProperties).animate(animationProperties, settings.animationSpeed, function() {
	                                isAnimationRunning = false;
	                                visibleImageIndex = nextImageIndex;
	                                initialiseHtmlFunc(carousel);
	                                
	                                if (magico.utilities.isFunction(settings.onImageChange)) {
	                                    settings.onImageChange.call(carousel, stopAnimation);
	                                }
	                                
	                                if (isTimerPaused) {
	                                    startAnimation(carousel);
	                                }
	                            });
	                        }, timeDelay);
                        } else {
	                        setTimeout(function() {
	                            $(item).css(cssProperties).animate(animationProperties, settings.animationSpeed);
	                        }, timeDelay);                    
                        }
                    });
                    
	                timeDelay += animationDelay;
	            });
	        }
	        
	        function animateSlider(carousel, imgToShow) {
	            if (typeof imgToShow !== "undefined" && isNaN(parseInt(imgToShow, 10)) === false) {
	                visibleImageIndex = parseInt(imgToShow, 10);
	            }
	        
		        var slider = $(carousel).children(":first"),
		            widthToInc = $(slider).children(":eq(" + visibleImageIndex + ")").width(),
		            currentLeftPos = parseFloat($(slider).css("left").replace("px", "")),
		            newLeftPos = currentLeftPos - widthToInc;

		        if (newLeftPos <= (totalWidth * -1)) { 
		            newLeftPos = 0; 
		        }

	            pauseAnimation();
	            
		        $(slider).animate({ "left": newLeftPos }, settings.animationSpeed, function() {
                    if (isTimerPaused) {
                        startAnimation(carousel);
                    }
		        });
	        }
	        
	        function fadeInExpandBoxes(carousel, arrayOfBoxes, delay) {
	            var boxWidth = $(carousel).width() / boxColumns,
	                boxHeight = $(carousel).height() / boxRows,
	                animationProps = { height: boxHeight + "px", opacity: 1, width: boxWidth + "px" },
	                cssProps = { height: 0, width: 0 };
	                
	            animateBoxes(carousel, arrayOfBoxes, animationProps, initialiseHtmlForBoxes, cssProps, delay);
            }
            
	        function fadeInExpandXBoxes(carousel, arrayOfBoxes, delay) {
	            var boxWidth = $(carousel).width() / boxColumns,
	                animationProps = { opacity: 1, width: boxWidth + "px" },
	                cssProps = { width: 0 };
	                
	            animateBoxes(carousel, arrayOfBoxes, animationProps, initialiseHtmlForBoxes, cssProps, delay);
            }
            
	        function fadeInExpandYBoxes(carousel, arrayOfBoxes, delay) {
	            var boxHeight = $(carousel).height() / boxRows,
	                animationProps = { height: boxHeight + "px", opacity: 1 },
	                cssProps = { height: 0 };
	                
	            animateBoxes(carousel, arrayOfBoxes, animationProps, initialiseHtmlForBoxes, cssProps, delay);
            }
            
            function fadeInBoxes(carousel, arrayOfBoxes, delay) {
	            animateBoxes(carousel, arrayOfBoxes, { opacity: 1 }, initialiseHtmlForBoxes, null, delay);
            }
            	        
	        function slideDownBoxes(carousel, arrayOfSlices, delay) {
	            var boxHeight = $(carousel).height() / boxRows,
	                animationProps = { height: boxHeight + "px" },
	                cssProps = { opacity: 1 };
	            
	            animateBoxes(carousel, arrayOfSlices, animationProps, initialiseHtmlForSlices, cssProps, delay);
	        }
	        	        	        
	        function slideUpBoxes(carousel, arrayOfSlices, delay) {
	            var boxHeight = $(carousel).height() / boxRows,
	                animationProps = { height: boxHeight + "px" },
	                cssProps = { bottom: "0px", opacity: 1, top: "" };
	            
	            animateBoxes(carousel, arrayOfSlices, animationProps, initialiseHtmlForSlices, cssProps, delay);
	        }
	        	        	        
	        function slideRightBoxes(carousel, arrayOfSlices, delay) {
	            var boxWidth = $(carousel).width() / boxColumns,
	                animationProps = { width: boxWidth + "px" },
	                cssProps = { height: $(carousel).height() / boxRows, opacity: 1, width: "0px" };
	            
	            animateBoxes(carousel, arrayOfSlices, animationProps, initialiseHtmlForSlices, cssProps, delay);
	        }
	        
	        function slideLeftBoxes(carousel, arrayOfSlices, delay) {
	            var boxWidth = $(carousel).width() / boxColumns,
	                animationProps = { width: boxWidth + "px" },
	                cssProps = { height: $(carousel).height() / boxRows, left: "", right: "0px", opacity: 1, width: "0px" };
	            
	            animateBoxes(carousel, arrayOfSlices, animationProps, initialiseHtmlForSlices, cssProps, delay);
	        }
	        /* End of Animation Functions */
	        	        	        
	        function setDefaultsForBoxes(displayImageFunc, cols, rows) {
	            htmlSetup = initialiseHtmlForBoxes;
	            displayImage = displayImageFunc;
    	        initialCssProps = null;
	            boxColumns = cols;
	            boxRows = rows;
	        }
	        
	        function setDefaultsForSlices(displayImageFunc, cols) {
    	        htmlSetup = initialiseHtmlForSlices;
	            displayImage = displayImageFunc;
    	        initialCssProps = { "height": "1px" };
	            boxColumns = cols;
    	        boxRows = 1;
	        }
	        
	        function consoleWrite(msg) {
	            if (settings.enableDebug === true) {
	                magico.utilities.writeToConsole(msg);
	            }
	        }

	        /* End of Base functions */

            /***************************************/
	        /***** ENTER CUSTOM EFFECTS HERE *****/
	        /***************************************/
	        
	        /* Random Box/Slice Effect */
	        this.initialiseRandom = function (carousel) {
	            isRandom = true;
	            htmlSetup = initialiseHtmlForBoxes;
	        };
	        
	        /* Slide Left Effect */
	        this.initialiseSlideLeft = function (carousel) {
	            htmlSetup = initialiseHtmlForSlideHorizontal;
	            displayImage = displayImageSlideLeft;
	        };
    	    
	        function displayImageSlideLeft(carousel, imgToShow) {
	            animateSlider(carousel, imgToShow);
	        }
    	    
    	    /* Fade Effect */
	        this.initialiseFadeBox = function (carousel) { setDefaultsForBoxes(displayImageFadeBox, 1, 1); };
	        function displayImageFadeBox(carousel) { fadeInBoxes(carousel, $("." + classForBoxes, carousel)); }
	        
	        /* Fade Box Down Right Effect */
	        this.initialiseFadeBoxDownRight = function (carousel) { setDefaultsForBoxes(displayImageFadeBoxDownRight, 8, 4); };
	        function displayImageFadeBoxDownRight(carousel) { fadeInExpandBoxes(carousel, $("." + classForBoxes, carousel), 20); }
    	    
	        /* Fade Box Up Left Effect */
	        this.initialiseFadeBoxUpLeft = function (carousel) { setDefaultsForBoxes(displayImageFadeBoxUpLeft, 8, 4); };
	        function displayImageFadeBoxUpLeft(carousel) { fadeInExpandBoxes(carousel, $("." + classForBoxes, carousel).reverse(), 20); }
    	    
	        /* Fade Box Down Effect */
	        this.initialiseFadeBoxDown = function (carousel) { setDefaultsForBoxes(displayImageFadeBoxDown, 1, 4); };
	        function displayImageFadeBoxDown(carousel) { fadeInExpandYBoxes(carousel, $("." + classForBoxes, carousel), 150); }
    	    
	        /* Fade Box Up Effect */
	        this.initialiseFadeBoxUp = function (carousel) { setDefaultsForBoxes(displayImageFadeBoxUp, 1, 4); };
	        function displayImageFadeBoxUp(carousel) { fadeInExpandYBoxes(carousel, $("." + classForBoxes, carousel).reverse(), 150); }

	        /* Fade Box Right Effect */
	        this.initialiseFadeBoxRight = function (carousel) { setDefaultsForBoxes(displayImageFadeBoxRight, 12, 1); };
	        function displayImageFadeBoxRight(carousel) { fadeInExpandXBoxes(carousel, $("." + classForBoxes, carousel), 60); }

	        /* Fade Box Left Effect */
	        this.initialiseFadeBoxLeft = function (carousel) { setDefaultsForBoxes(displayImageFadeBoxLeft, 12, 1); };
	        function displayImageFadeBoxLeft(carousel) { fadeInExpandXBoxes(carousel, $("." + classForBoxes, carousel).reverse(), 60); }

	        /* Fade Box Random Effect */
	        this.initialiseFadeBoxRandom = function (carousel) {
    	        setDefaultsForBoxes(displayImageFadeBoxRandom, 12, 5);
	        };
	        function displayImageFadeBoxRandom(carousel) {
	            var originalArray = $("." + classForBoxes, carousel).toArray(),
	                sortedArray = [];
	            
	            while(originalArray.length > 0) {
	                var randomNum = Math.floor(Math.random() * (originalArray.length));
	                sortedArray.push(originalArray[randomNum]);
	                originalArray.remove(randomNum);
	            }
	            
	            fadeInExpandBoxes(carousel, sortedArray, 15);
	        }
    	    
	        /* Slice Down Right Effect */    	    
    	    this.initialiseSliceDownRight = function (carousel) { setDefaultsForSlices(displayImageSliceDownRight, 10); };
    	    function displayImageSliceDownRight(carousel) { slideDownBoxes(carousel, $("." + classForBoxes, carousel), 100); }
    	    
	        /* Slice Down Left Random Effect */    	    
    	    this.initialiseSliceDownLeft = function (carousel) { setDefaultsForSlices(displayImageSliceDownLeft, 10); };
    	    function displayImageSliceDownLeft(carousel) { slideDownBoxes(carousel, $("." + classForBoxes, carousel).reverse(), 100); }
    	    
	        /* Slice Down Effect */    	    
    	    this.initialiseSliceDown = function (carousel) { setDefaultsForSlices(displayImageSliceDown, 1); };
    	    function displayImageSliceDown(carousel) { slideDownBoxes(carousel, $("." + classForBoxes, carousel), 100); }
    	    
	        /* Slice Up Effect */    	    
    	    this.initialiseSliceUp = function (carousel) { setDefaultsForSlices(displayImageSliceUp, 1); };
    	    function displayImageSliceUp(carousel) { slideUpBoxes(carousel, $("." + classForBoxes, carousel), 100); }
    	    
	        /* Slice Right Effect */    	    
    	    this.initialiseSliceRight = function (carousel) { setDefaultsForSlices(displayImageSliceRight, 1); };
    	    function displayImageSliceRight(carousel) { slideRightBoxes(carousel, $("." + classForBoxes, carousel), 100); }
    	    
	        /* Slice Left Effect */    	    
    	    this.initialiseSliceLeft = function (carousel) { setDefaultsForSlices(displayImageSliceLeft, 1); };
    	    function displayImageSliceLeft(carousel) { slideLeftBoxes(carousel, $("." + classForBoxes, carousel), 100); }
    	    
	        /* END OF CUSTOM FUNCTIONS */
	        
	        this.startPlugin = function() {
                initialiseBase(carousel);
                
                var initialiseFunc = thisCarousel["initialise" + settings.effect];
                
                if (initialiseFunc instanceof Function) {
                    initialiseFunc(carousel);
                } else {
                    this.initialiseSlideLeft(carousel);
                }
                
	            setActiveImageLink(0);
                htmlSetup(carousel);
                setHoverActions(carousel);
                setKeyboardActions(carousel);
                setClickActions(carousel);
                startAnimation(carousel);
	        }
	        
	        this.startPlugin();
	    };
	    
	    function displayLoadingImage(carousel) {
	        var carouselDim = new magico.dimensions(carousel);
	        
	        $(carousel).append(
	            $("<img class='" + settings.loadingImageClass + "' src='" + settings.loadingImage + "' alt='Loading...' />")
	            .css({
	                display: "block",
	                position: "absolute",
	                top: (carouselDim.getHeight() / 2),
	                left: (carouselDim.getWidth() / 2)
	            })
	        );
	    }
	    
	    function setupCarousel(carousel) {
            var magicoCarousel = new magiCarouselManager(carousel);
            $("." + settings.loadingImageClass).fadeOut(settings.animationSpeed, function () {
                $(this).remove();
            });
	    }
	    
        return this.each(function (i, carousel) {
            $(carousel).css("overflow", "hidden").children().hide();
            
            if (settings.enableTestMode) {
                setupCarousel(carousel);
            } else {
                $(window).load(function() {
                    setupCarousel(carousel);
                });
            }
                        
            displayLoadingImage(carousel);
        });
	};
}(jQuery));

/* Magico plugin for displaying product images */
(function($) {
    $.fn.magipix = function (options) {
        var settings = $.extend({
            activeThumbClass:           "magipix_current",         
            animationSpeed:             500,
            closeImage:                 "/img/close.gif",
            closeImageId:               "magipix-close",
            enableDebug:                true,
            enableEditMode:             false,
            enableZoom:                 true,
            errorBoxCss:                {},
            errorBoxFadeOutTime:        4000,
            errorBoxId:                 "magipix-error",
            galleryImageActiveClass:    "active",
            galleryImagePopupCss:       {},
            galleryImagePreload:        false,
            galleryLoadingId:           "magipix-gallery-loading",
            galleryPopupImageId:        "magipix-gallery-popup",
            gallerySelector:            "",
            imageToExpandFrom:          "",
            isModal:                    true,
            largeImageBorderWidth:      2,
            largeImageCss:              {},
            largeImageId:               "magipix-large-img",
            largeImageTopBuffer:        15,
            loadingContainerId:         "magipix-loading-container",
            loadingImage:               "/img/ajax-loader.gif",
            loadingImageBoxCss:         {},
            loadingImageBoxHeight:      60,
            loadingImageBoxText:        "LOADING...",
            loadingImageForGallery:     "/img/ajax-loader.gif",
            loadingImageId:              "magipix-zoom-load",
            modalCss:                   {},
            modalId:                    "magipix-modal",
            modalOpacity:               0.8,
            nextImage:                  "/img/next.gif",
            nextImageId:                "magipix-next",
            popupBackground:            "#fff",
            popupBorderColor:           "#ACA8A3",
            popupBorderWidth:           2,
            previousImage:              "/img/prev.gif",
            previousImageId:            "magipix-prev",
            productImages:              {},
            productTitleId:             "magipix-prod-title",
            viewLargeLinkSelector:      "",
            zoomAreaContainerCss:       {},
            zoomContainerCss:           {},
            zoomImageAreaBorderWidth:   1,
            zoomImageAreaContainerId:   "magipix-zoom-area",
            zoomImageBorderWidth:       1,
            zoomImageContainerId:       "magipix-zoom",
            zoomImageLeftOffset:        3,
            zoomImageTopOffset:         0,
            zoomImagePreload:           true,
            zoomAreaType:               "reverse" /* Options: 'reverse' & 'standard' */
        }, options),
        
        consoleWrite = function (msg) {
            if (settings.enableDebug === true) {
	            magico.utilities.writeToConsole(msg);
            }
        },
        
        /* This function represents the error box thats displayed whenever there's
           an image load error */
        magipixErrorBox = function (mainImage) {
            this.timeoutForFadeOut = null;
            
            this.clearExisting = function () {
                $("#" + settings.errorBoxId).remove();
                clearTimeout(this.timeoutForFadeOut);
            };
            
            this.display = function (msg, positionElement, isFadeOut) {
                if (!positionElement) { positionElement = mainImage.getMainImage(); }
                if (!msg) { msg = "Error loading"; }
                if (!isFadeOut) { isFadeOut = true; }
                
                /* Want to clear existing error box if it exists */
                this.clearExisting();
                
                var dimensions = new magico.dimensions(positionElement),
                    errorBox = $("<div />").attr("id", settings.errorBoxId).css(getCss(dimensions)).append(msg);
                    
                $("body").append(errorBox);
                
                /* Need to reposition the error box after it's added to the page because
                   when it was initially added, the height was unknown the therefore we
                   need to adjust the top css value to position the box correctly */
                repositionBox(dimensions);
                
                $("#" + settings.errorBoxId).animate({ opacity: 1 }, settings.animationSpeed);
                
                if (isFadeOut) {
                    this.setRemoveTimeout();
                }
            };
            
            this.fadeOutErrorBox = function () {
                var thisErrorBox = this;
                $("#" + settings.errorBoxId).fadeOut(settings.animationSpeed, function () {
                    thisErrorBox.remove();
                });
            };
            
            this.remove = function () {
                $("#" + settings.errorBoxId).remove();
            };
            
            this.setRemoveTimeout = function () {
                var thisErrorBox = this;
                
                this.timeoutForFadeOut = setTimeout(function () {
                    thisErrorBox.fadeOutErrorBox();
                }, settings.errorBoxFadeOutTime);
            };
            
            function getCss(dimensions) {
                var padding = 3;
                
                return $.extend({
                    backgroundColor: "#ffcccc",
                    border: "1px solid #cc0033",
                    color: "#cc0033",
                    left: dimensions.left(),
                    opacity: 0,
                    padding: padding + "px",
                    position: "absolute",
                    top: dimensions.top(),
                    width: dimensions.getWidth() - (padding * 2),
                    zIndex: 1100
                }, settings.errorBoxCss);
            }
            
            function repositionBox(elementDim) {
                var errorDim = new magico.dimensions("#" + settings.errorBoxId);

                $("#" + settings.errorBoxId).css({
                    top: elementDim.top() - errorDim.getHeight() - 3
                });
            }
        },
        
        /* This function represents the gallery of images below the main image */
        magipixGalleryImage = function (mainImage) {
            this.isAnimating = false;
            this.afterGalleryImageLoadError = function () {};
            this.afterHide = function () {};
        
            this.animate = function (imageIndex) {
                /* Need to check here that there isn't already an animation taking place
                   before starting an animation */
                if (this.isAnimating === false) {
                    var selectedImage = $(settings.gallerySelector).eq(imageIndex).find("img"),
                        mainImageDim = new magico.dimensions(mainImage.getMainImage()),
                        mediumImage = settings.productImages.medium[imageIndex],
                        imageCss = getCss(selectedImage),
                        imageToAnimate = $("<img />").attr("id", settings.galleryPopupImageId).attr("src", mediumImage).css(imageCss),
                        thisGallery = this;
                    
                    this.setActive(imageIndex);
                    $("#" + settings.galleryPopupImageId).remove();
                    $("body").append(imageToAnimate); 
                   
                    showLoading(imageToAnimate);
                    
                    /* Checking if the image is already loaded. If not, bind a function to the load event */
                    if ($("#" + settings.galleryPopupImageId).height() == 0) {
                        $("#" + settings.galleryPopupImageId).load(function () {
                            $("#" + settings.galleryPopupImageId).unbind("load");
                            thisGallery.animateToFull(mainImageDim, imageIndex);
                        }).error(function () {
                            $(this).unbind("error");
                            thisGallery.afterGalleryImageLoadError("Error loading gallery image", imageIndex);
                            thisGallery.removeLoading();
                            thisGallery.remove();
                        });
                    } else {
                        thisGallery.animateToFull(mainImageDim, imageIndex);
                    }
                }
            };
            
            this.animateToFull = function (mainImageDim, imageIndex) {
                var thisGallery = this;
                
                this.isAnimating = true;
                
                $("#" + settings.galleryPopupImageId).animate({
                    height: mainImageDim.getHeight(),
                    left: mainImageDim.left(),
                    top: mainImageDim.top(),
                    width: mainImageDim.getWidth()
                }, settings.animationSpeed, function () {
                    thisGallery.hide(imageIndex);
                });            
            };
            
            this.hide = function (imageIndex) {
                var thisGallery = this;
                
                mainImage.setImage(imageIndex, function () {
                    thisGallery.afterHide();
                    thisGallery.isAnimating = false;
                    thisGallery.removeLoading();                    
                });
            };
            
            this.remove = function () {
                $("#" + settings.galleryPopupImageId).remove();
            };
            
            this.removeLoading = function() {
                $("#" + settings.galleryLoadingId).remove();
            };
            
            this.setActive = function (imageIndex) {
                $(settings.gallerySelector)
                .find("a")
                .removeClass(settings.galleryImageActiveClass)
                .eq(imageIndex)
                .addClass(settings.galleryImageActiveClass);
            };
            
            function getCss(image) {
                var imageDim = new magico.dimensions(image);
                
                return $.extend({
                    height: imageDim.height(),
                    left: imageDim.left(),
                    position: "absolute",
                    top: imageDim.top(),
                    width: imageDim.width()
                }, settings.galleryImagePopupCss);
            }
            
            function getCssForLoading(image) {
                var imageDim = new magico.dimensions(image);
                
                return {
                    background: "transparent url('" + settings.loadingImageForGallery + "') center center no-repeat",
                    height: imageDim.height(),
                    left: imageDim.left(),
                    position: "absolute",
                    top: imageDim.top(),
                    width: imageDim.width()
                };
            }
            
            function showLoading(imageToAnimate) {
                var galleryDim = new magico.dimensions(imageToAnimate),
                    galleryLoadingEl = $("<div />").attr({ 
                        id: settings.galleryLoadingId
                    }).css(getCssForLoading(imageToAnimate));
                    
                $("body").append(galleryLoadingEl);
            }
        },
        
        /* This function represents the large image that's displayed when the main image is clicked */
        magipixLargeImage = function (mainImage) {
            var isLoaded = false,
                dimensions = {
                    height: 0,
                    width: 0
                };
            
            this.isDisplayed = false;
            this.afterClosing = function () {};
            this.afterImageChange = function () {};
            this.afterLargeImageLoadError = function () {};
            this.afterNewLargeImageLoadError = function () {};
            this.afterModalShown = function () {};
            this.animateShowModal = function () {};
            this.beforeAddingToPage = function () {};
            this.beforeAnimateToFull = function () {};
            this.beforeHideAnimation = function () {};
            this.beforePreloadingNewImage = function () {};
            this.beforeSettingNewImage = function () {};
            
            this.afterImageLoaded = function (largeImage) {
                var thisLargeImage = this;
                                
                if (settings.isModal) {
                    this.animateShowModal();
                } else {
                    thisLargeImage.animateToFull();
                }
            };
            
            this.animateToFull = function() {
                var newTop = ($(window).height() / 2) - (dimensions.height / 2) + $(window).scrollTop(),
                    newLeft = ($(window).width() / 2) - (dimensions.width / 2),
                    thisLargeImage = this;
                    
                if (newTop < settings.largeImageTopBuffer) {
                    newTop = settings.largeImageTopBuffer;
                }
                    
                this.beforeAnimateToFull();
                $("#" + settings.largeImageId).animate({
                    height: dimensions.height,
                    left: newLeft,
                    top: newTop,
                    width: dimensions.width
                }, settings.animationSpeed, function () {
                    thisLargeImage.displayControls();
                });
            };
            
            this.display = function () {
                this.isDisplayed = true;
                this.loadLargeImage();
            };
            
            this.displayCloseButton = function () {
                var imageDim = new magico.dimensions("#" + settings.largeImageId),
                    closeDim = new magico.dimensions("#" + settings.closeImageId),
                    thisLargeImage = this;
            
                $("#" + settings.closeImageId).css({
                    cursor: "pointer",
                    display: "block",
                    left: imageDim.left() + imageDim.getWidth() - (closeDim.width() / 2),
                    position: "absolute",
                    top: imageDim.top() - (closeDim.height() / 2),
                    zIndex: 1200
                }).click(function () {
                    thisLargeImage.hide();
                }).fadeIn(settings.animationSpeed); 
            };
            
            this.displayControls = function () {
                var thisLargeImage = this,
                    hideCss = { display: "none" },
                    productTitle = mainImage.getMainImageTitle(),
                    closeElement = $("<img />").attr({ id: settings.closeImageId, src: settings.closeImage }).css(hideCss),
                    prevElement = $("<img />").attr({id: settings.previousImageId, src: settings.previousImage }).css(hideCss),
                    nextElement = $("<img />").attr({id: settings.nextImageId, src: settings.nextImage }).css(hideCss),
                    prodTitleElement = $("<div />").attr({id: settings.productTitleId }).css(hideCss).append(productTitle);
                
                $("body").append(closeElement);
                $("#" + settings.closeImageId).load(function () {
                    $(this).unbind("load");
                    thisLargeImage.displayCloseButton();
                });
                
                if (!!productTitle) {
                    $("body").append(prodTitleElement);
                    thisLargeImage.displayProductTitle();
                }
                
                if (!!settings.productImages.large && settings.productImages.large.length > 1) {
                    $("body").append(prevElement);
                    $("#" + settings.previousImageId).load(function () {
                        $(this).unbind("load");
                        thisLargeImage.displayPreviousButton();
                    });
                    
                    $("body").append(nextElement);
                    $("#" + settings.nextImageId).load(function () {
                        $(this).unbind("load");
                        thisLargeImage.displayNextButton();
                    });
                }
            };
            
            this.displayNewImage = function (newImageIndex) {
                var thisLargeImage = this,
                    newImage = settings.productImages.large[newImageIndex],
                    newMainImage = settings.productImages.medium[newImageIndex];
                
                this.beforePreloadingNewImage($("#" + settings.largeImageId));
                magico.utilities.preloadImage(newImage, function (loadedImage) { 
                    setActiveGalleryImage(newImageIndex);
                    thisLargeImage.setImage(loadedImage);
                }, function () {
                    thisLargeImage.afterNewLargeImageLoadError("Error loading image");
                });
                
                magico.utilities.preloadImage(newMainImage, function (loadedImage) { 
                    thisLargeImage.setMainImage(loadedImage);
                    thisLargeImage.afterImageChange(newImageIndex);
                }, function () {
                    thisLargeImage.afterNewLargeImageLoadError("Error loading image");
                });
                
                return false;
            };
            
            this.displayNextButton = function () {
                var imageDim = new magico.dimensions("#" + settings.largeImageId),
                    nextDim = new magico.dimensions("#" + settings.nextImageId),
                    thisLargeImage = this;
            
                $("#" + settings.nextImageId).css({
                    cursor: "pointer",
                    display: "block",
                    left: imageDim.left() + imageDim.getWidth(),
                    position: "absolute",
                    top: imageDim.top() + (imageDim.getHeight() / 2) - (nextDim.height() / 2),
                    zIndex: 1200
                }).click(function () {
                    thisLargeImage.displayNextImage();
                }).fadeIn(settings.animationSpeed); 
            };
            
            this.displayNextImage = function () {
                var currentImageIndex = settings.productImages.large.indexOf($("#" + settings.largeImageId).attr("src")),
                    nextImageIndex = currentImageIndex + 1;
                    
                if (nextImageIndex >= settings.productImages.large.length) { nextImageIndex = 0; }
                    
                this.displayNewImage(nextImageIndex);
            };
            
            this.displayPreviousButton = function () {
                var imageDim = new magico.dimensions("#" + settings.largeImageId),
                    previousDim = new magico.dimensions("#" + settings.previousImageId),
                    thisLargeImage = this;
            
                $("#" + settings.previousImageId).css({
                    cursor: "pointer",
                    display: "block",
                    left: imageDim.left() - previousDim.width(),
                    position: "absolute",
                    top: imageDim.top() + (imageDim.getHeight() / 2) - (previousDim.height() / 2),
                    zIndex: 1200
                }).click(function () {
                    thisLargeImage.displayPreviousImage();
                }).fadeIn(settings.animationSpeed); 
            };
            
            this.displayPreviousImage = function () {
                var currentImageIndex = settings.productImages.large.indexOf($("#" + settings.largeImageId).attr("src")),
                    prevImageIndex = currentImageIndex - 1;
                    
                if (prevImageIndex < 0) { prevImageIndex = settings.productImages.large.length - 1; }
                    
                this.displayNewImage(prevImageIndex);
            };
            
            this.displayProductTitle = function () {
                var imageDim = new magico.dimensions("#" + settings.largeImageId),
                    productTitleDim = new magico.dimensions("#" + settings.productTitleId),
                    thisLargeImage = this;
            
                $("#" + settings.productTitleId).css({
                    backgroundColor: "#fff",
                    display: "block",
                    fontWeight: "bold",
                    left: imageDim.left() + settings.largeImageBorderWidth,
                    opacity: 0.8,
                    padding: "3px 0 0 10px",
                    position: "absolute",
                    textAlign: "left",
                    top: imageDim.top() + settings.largeImageBorderWidth,
                    width: imageDim.getWidth() - (10 + (settings.largeImageBorderWidth * 2)),
                    zIndex: 1200
                }).fadeIn(settings.animationSpeed);             
            };
            
            this.hide = function () {
                var imageDim = new magico.dimensions(mainImage.getMainImage()),
                    thisLargeImage = this;
                
                $("img#" + settings.closeImageId).remove();
                $("img#" + settings.previousImageId).remove();
                $("img#" + settings.nextImageId).remove();
                $("#" + settings.productTitleId).remove();
                this.beforeHideAnimation();
                
                $("#" + settings.largeImageId).animate({
                    height: imageDim.getHeight(),
                    left: imageDim.left() - settings.largeImageBorderWidth,
                    top: imageDim.top() - settings.largeImageBorderWidth,
                    width: imageDim.getWidth()
                }, settings.animationSpeed, function () {
                    thisLargeImage.afterClosing();
                });
                
                return false;
            };
            
            this.loadLargeImage = function () {
                var imageDim = new magico.dimensions(mainImage.getMainImage()),
                    cssVals = getCss(imageDim),
                    thisLargeImage = this,
                    largeImage = mainImage.getLargeImageLink(),
                    largeImageElement = $("<img />").load(function () {
                        $(this).unbind("load");
                        dimensions = magico.utilities.getImageDimensions(largeImage);
                        thisLargeImage.afterImageLoaded(largeImage);
                    }).error(function () {
                        $(this).unbind("error");
                        thisLargeImage.afterLargeImageLoadError("Error loading large image");
                        thisLargeImage.remove();
                    }).attr({ 
                        id: settings.largeImageId, src: largeImage 
                    }).css(cssVals);
                
                hideSelectElements();
                
                this.beforeAddingToPage();
                $("body").append(largeImageElement);
            };
            
            this.remove = function () {
                this.isDisplayed = false;
                $("#" + settings.largeImageId).remove();
            };
            
            this.setImage = function (image) {
                this.beforeSettingNewImage();
                $("#" + settings.largeImageId).attr("src", image);
                $(mainImage.getLargeImage()).attr("href", image);
            };
            
            this.setMainImage = function (image) {
                $(mainImage.getMainImage()).attr("src", image);
            };
            
            function getCss(imageDim) {
                return $.extend({
                    border: settings.largeImageBorderWidth + "px solid #b4b4b4",
                    height: imageDim.getHeight(),
                    left: imageDim.left() - settings.largeImageBorderWidth,
                    overflow: "hidden",
                    position: "absolute",
                    top: imageDim.top() - settings.largeImageBorderWidth,
                    width: imageDim.getWidth(),
                    zIndex: 1000
                }, settings.largeImageCss);
            }
            
            function getCssForClose(imageDim, closeDim) {
                return {
                    display: "block",
                    left: closeImageLeft - ($("a." + closeImageLink + " > img").height() / 2) + (settings.popupPadding * 2),
                    position: "absolute",
                    top: largeImgTop - ($("a." + closeImageLink + " > img").width() / 2),
                    width: "auto",
                    zIndex: 1200
                };
            }
            
            function hideSelectElements() {
                /* Have to hide select inputs in IE6 when image is popped up because they appear on top of all other elements */
                if ($.browser.msie && $.browser.version == 6) {
                    $("select").css("visibility", "hidden");
                } 
            }
            
            function setActiveGalleryImage(imageIndex) {
                $(settings.gallerySelector)
                .find("a")
                .removeClass(settings.galleryImageActiveClass)
                .eq(imageIndex)
                .addClass(settings.galleryImageActiveClass);
            }
        },
        
        magipixLoadingImage = function (mainImage) {
            this.mouseOnLoadingBox = false;
            
            this.display = function (positioningElement) {
                this.hide();
                if (magico.utilities.isNullOrEmpty(positioningElement)) {
                    positioningElement = mainImage.getMainImage();
                }
                
                var imageDim = new magico.dimensions(positioningElement),
                    loadingBox = $("<div />").attr("id", settings.loadingImageId).append(settings.loadingImageBoxText).css(getCss(imageDim));
                
                $("body").append(loadingBox);
            };
            
            this.hide = function () {
                $("#" + settings.loadingImageId).remove();
                $("#" + settings.loadingContainerId).remove();
            };

            function getCss(imageDim) {
                var imageBgTop = (settings.loadingImageBoxHeight / 2);
            
                return $.extend({
                    background: "url(" + settings.loadingImage + ") no-repeat scroll center " + imageBgTop + "px #FFFFFF",
                    border: "1px solid #ccc",
                    fontSize: "10px",
                    height: settings.loadingImageBoxHeight + "px",
                    left: imageDim.left() + (imageDim.getWidth() / 4),
                    opacity: 0.9,
                    paddingTop: "10px",
                    position: "absolute",
                    top: imageDim.top() + (imageDim.getHeight() / 2) - (settings.loadingImageBoxHeight / 2),
                    width: imageDim.getWidth() / 2,
                    zIndex: 4000
                }, settings.loadingImageBoxCss);
            }

            function getCssForContainer(imageDim) {
                return {
                    height: imageDim.getHeight() + 10,
                    left: imageDim.left() - 5,
                    opacity: 1,
                    position: "absolute",
                    top: imageDim.top() - 5,
                    width: imageDim.getWidth() + 10,
                    zIndex: 3500
                };
            }
        },
        
        magipixMainImage = function (mainImage) {
            this.afterNewImageLoadError = function () {};
        
            this.afterNewImagePreload = function (newImage, imageIndex, afterChange) {
                $(this.getMainImage()).attr("src", newImage);
                $(this.getLink()).attr("href", settings.productImages.large[imageIndex]);
                
                setTimeout(function () {                
                    $("#" + settings.galleryPopupImageId).remove();
                    afterChange();
                }, 100);
            };
            
            this.getLargeImage = function () {
                if (mainImage.tagName.toLowerCase() === "a") {
                    return $(mainImage);
                } else {
                    var parentLinks = $(mainImage).parents("a");
                    
                    if (magico.utilities.isNullOrEmpty(parentLinks)) {
                        return null;
                    } else {
                        return $(parentLinks).eq(":first");
                    }
                }
            };
            
            this.getLargeImageLink = function () {
                var largeImage = this.getLargeImage();
                
                if (magico.utilities.isNullOrEmpty(largeImage) === false) {
                    return $(largeImage).attr("href");
                }
                
                return null;
            };
            
            this.getLink = function () {
                if (mainImage.tagName.toLowerCase() === "a") {
                    return mainImage;
                }
                
                return null;
            };
        
            this.getMainImage = function () {
                if (mainImage.tagName.toLowerCase() === "img") {
                    return $(mainImage);
                } else {
                    var childImages = $(mainImage).find("img");
                    
                    if (magico.utilities.isNullOrEmpty(childImages)) {
                        return null;
                    } else {
                        return childImages[0];
                    }
                }
            };
            
            this.getMainImageLink = function () {
                var mainImageElement = this.getMainImage();
                if (magico.utilities.isNullOrEmpty(mainImageElement) === false) {
                    return $(mainImageElement).attr("src");
                }
                
                return null;
            };
            
            this.getMainImageTitle = function () {
                return $(this.getMainImage()).attr("alt");
            };
            
            this.setImage = function (imageIndex, afterChange) {
                var thisMainImage = this;
                
                magico.utilities.preloadImage(settings.productImages.medium[imageIndex], function (image) {
                    thisMainImage.afterNewImagePreload(image, imageIndex, afterChange);
                });
            };
        },
        
        magipixModal = function() {
            this.afterHiding = function () {};
        
            this.animateShow = function (afterModalDisplayed) {
                var thisModal = this;
                
                $("body").append(
                    $("<div />").attr("id", settings.modalId).css(this.getCss())
                );
                
                $("#" + settings.modalId).animate({ 
                    opacity: settings.modalOpacity 
                }, settings.animationSpeed, function () {
                    afterModalDisplayed();
                });
            };
            
            this.getCss = function () {
                return $.extend({
                    backgroundColor: "#000",
                    height: $(document).height(),
                    left: 0,
                    opacity: 0,
                    position: "absolute",
                    top: 0,
                    width: $(window).width(),
                    zIndex: 900
                }, settings.modalCss);
            };
            
            this.hide = function (afterModalHidden) {
                var thisModal = this;
            
                $("#" + settings.modalId).animate({
                    opacity: 0
                }, settings.animationSpeed, function () {
                    $(this).remove();
                    thisModal.afterHiding();
                });
            };
            
            this.remove = function () {
                $("div#" + settings.modalId).remove();
            };
        },
        
        magipixZoomImage = function (mainImage) {
            var currentImageIndex = 0,
                dimensions = {
                    height: 0,
                    width: 0
                },
                heightRatio = 1,
                widthRatio = 1;
            
            this.afterHide = function () {};
            this.afterLoad = function () {};
            this.afterZoomImageLoadError = function () {};
            this.beforeZoomImageLoad = function () {};
            this.displayLarge = function () {};
            this.enabled = true;
            this.isLargeImageDisplayed = function () { return true; };
            this.isLoaded = false;
            this.isLoading = false;
            
            this.calculateRatios = function (ev, imageDim) {
                dimensions = {
                    height: $("#" + settings.zoomImageContainerId).find("img").height(),
                    width: $("#" + settings.zoomImageContainerId).find("img").width()
                };
                
                heightRatio = dimensions.height / imageDim.height();
                widthRatio = dimensions.width / imageDim.width();           
                
                if (this.enabled) {
                    if (heightRatio === 0 || widthRatio === 0) {
                        consoleWrite("Failed to load zoom");
                    } else {
                        setZoomedImageAreaDimensions(imageDim);
                        this.setZoomedImagePosition(ev);
                        this.displayZoomContainers();
                        this.setMouseEventsForZoomArea();
                        this.setIsLoaded();
                        this.afterLoad();
                    }
                } else {
                    this.hide();                
                }
            };           

            this.clickZoomArea = function () {
                this.hide();
                this.setDisabled();
                this.displayLarge();
                return false;
            };
            
            this.displayZoomContainers = function (){
                if (this.enabled) {                
                    var zoomAreaOpacityLevel = (settings.zoomAreaType.toLowerCase() === "reverse" ? 1 : 0.8);
                    
                    $("#" + settings.zoomImageContainerId).animate({ opacity: 1 }, 1);
                    $("#" + settings.zoomImageAreaContainerId).animate({ opacity: zoomAreaOpacityLevel }, 1);
                } else {
                    this.hide();                
                }
            };

            this.getZoomImage = function (index) {
                var image = "";
                if (magico.utilities.isNullOrEmpty(settings.productImages.zoom) === false) {
                    image = settings.productImages.zoom[index];
                } else if (magico.utilities.isNullOrEmpty(mainImage.getLargeImageLink()) === false) {
                    image = mainImage.getLargeImageLink();
                }
                
                if (!image) { image = "/"; }
                
                return image;
            };
            
            this.hide = function () {
                this.hideZoomImage();
                this.hideZoomArea();
                this.afterHide();
                $(mainImage.getMainImage()).css({ opacity: 1 });
            };
            
            this.hideZoomImage = function () {
                $("div#" + settings.zoomImageContainerId).hide();
            };
  
            this.hideZoomArea = function () {
                $("div#" + settings.zoomImageAreaContainerId).hide();                
            };
  
            this.load = function (ev, currentImgIndex) {
                currentImageIndex = currentImgIndex;
                
                if (this.isLoaded === false && this.isLoading === false && this.enabled) {
                    this.isLoading = true;
                    this.loadZoomContainer(ev);
                }
            };
            
            this.loadZoomContainer = function (ev) {
                var thisZoom = this,
                    imageDim = new magico.dimensions(mainImage.getMainImage()),
                    zoomImage = $("<img />").attr("src", this.getZoomImage(currentImageIndex)).css({ 
                        left: 0,
                        position: "absolute" ,
                        top: 0
                    }),
                    zoomImageInnerContainer = $("<div />").append(zoomImage),
                    zoomContainer = $("<div />").attr({
                        id: settings.zoomImageContainerId
                    }).css(getCssForZoomImage(imageDim)).append(zoomImageInnerContainer);
                
                if (this.enabled) {
                    $("body").append(zoomContainer);  
                    
                    if ($("#" + settings.zoomImageContainerId).find("img").height() > 0) {
                        thisZoom.loadZoomAreaContainer(ev, imageDim);
                    } else {
                        this.beforeZoomImageLoad();
                        $("#" + settings.zoomImageContainerId).find("img").load(function () {
                            $(this).unbind("load");
                            thisZoom.loadZoomAreaContainer(ev, imageDim);
                        }).error(function () {
                            $(this).unbind("error");
                            thisZoom.afterZoomImageLoadError("Error loading zoom");
                            thisZoom.resetZoom();
                        });
                    }                    
                } else {
                    this.hide();                
                }
            };
            
            this.loadZoomAreaContainer = function (ev, imageDim) {
                var thisZoom = this,
                    areaCss = getCssForZoomImageArea(),
                    zoomAreaImage = getZoomAreaImage(),
                    zoomAreaInner = $("<div />").append(zoomAreaImage),
                    zoomAreaContainer = $("<div />").attr("id", settings.zoomImageAreaContainerId).css(areaCss).append(zoomAreaInner);
                
                if (this.enabled) {
                    $("body").append(zoomAreaContainer);
                    
                    if ($("#" + settings.zoomImageAreaContainerId).find("img").length > 0) {
                        if ($("#" + settings.zoomImageAreaContainerId).find("img").height() > 0) {
                            thisZoom.calculateRatios(ev, imageDim);
                        } else {                                    
                            $("#" + settings.zoomImageAreaContainerId).find("img").load(function () {
                                $(this).unbind("load");
                                thisZoom.calculateRatios(ev, imageDim);
                            }).error(function () {
                                $(this).unbind("error");
                                thisZoom.afterZoomImageLoadError("Error loading zoom");
                                thisZoom.resetZoom();
                            });
                        }
                    } else {
                        thisZoom.calculateRatios(ev, imageDim);
                    }
                } else {
                    this.hide();                
                }
            };
            
            this.positionZoomers = function (ev) {
                if (this.enabled && this.isLoaded && this.isLargeImageDisplayed() === false) {
                    this.setZoomedImagePosition(ev);
                }
            };
            
            this.removeZoomImage = function() {
                $("div#" + settings.zoomImageContainerId).remove();
            };
            
            this.removeZoomArea = function () {
                $("div#" + settings.zoomImageAreaContainerId).remove();                
            };
            
            this.resetZoom = function () {
                this.removeZoomImage();
                this.removeZoomArea();
                this.isLoaded = false;
                this.isLoading = false;
            };
            
            this.setDisabled = function () {
                this.enabled = false;
            };
            
            this.setEnabled = function () {
                this.enabled = true;
            };
  
            this.setIsLoaded = function () {
                this.isLoading = false;
                this.isLoaded = true;
            };
            
            this.setMouseEventsForZoomArea = function() {
                var thisZoom = this;
                
                $("#" + settings.zoomImageAreaContainerId).bindOnce("click", function () {
                    thisZoom.clickZoomArea.call(thisZoom);
                });
            };
            
            this.setZoomedImagePosition = function (ev) {
                var imageDim = new magico.dimensions(mainImage.getMainImage()),
                    posX = ev.pageX - imageDim.left(),
                    posY = ev.pageY - imageDim.top(),
                    zoomAreaH = imageDim.height() / heightRatio,
                    zoomAreaW = imageDim.width() / widthRatio,
                    zoomAreaLeft = ev.pageX - (zoomAreaW / 2),
                    zoomAreaTop = ev.pageY - (zoomAreaH / 2),
                    zoomAreaPositionLeft = posX - (zoomAreaW / 2),
                    zoomAreaPositionTop = posY - (zoomAreaH / 2),
                    bgPosX = (zoomAreaPositionLeft * widthRatio) * -1,
                    bgPosY = (zoomAreaPositionTop * heightRatio) * -1,
                    maxX = (dimensions.width - (dimensions.width / widthRatio)) * -1,
                    maxY = (dimensions.height - (dimensions.height / heightRatio)) * -1,
                    maxZoomAreaLeft = imageDim.left() + imageDim.width() - zoomAreaW,
                    maxZoomAreaTop = imageDim.top() + imageDim.height() - zoomAreaH;
                
                if (bgPosX > 0) { bgPosX = 0; } 
                else if (bgPosX < maxX) { bgPosX = maxX; }
                
                if (bgPosY > 0) { bgPosY = 0; } 
                else if (bgPosY < maxY) { bgPosY = maxY; }
                
                if (zoomAreaLeft < imageDim.left()) { zoomAreaLeft = imageDim.left(); }
                else if (zoomAreaLeft > maxZoomAreaLeft) { zoomAreaLeft = maxZoomAreaLeft; }
                
                if (zoomAreaTop < imageDim.top()) { zoomAreaTop = imageDim.top(); }
                else if (zoomAreaTop > maxZoomAreaTop) { zoomAreaTop = maxZoomAreaTop; }

                $("#" + settings.zoomImageContainerId).find("img").css({
                    left: bgPosX,
                    top: bgPosY
                }).end().show();
                
                setZoomedImageAreaPosition(zoomAreaLeft, zoomAreaTop, imageDim);
            };
            
            function getCssForZoomImage(imageDim) {
                return $.extend({
                    border: settings.zoomImageBorderWidth + "px solid #ccc",                        
                    height: imageDim.getHeight() - (settings.zoomImageBorderWidth * 2),
                    left: imageDim.left() + imageDim.getWidth() + settings.zoomImageLeftOffset,
                    opacity: 0,
                    overflow: "hidden",
                    position: "absolute",
                    top: imageDim.top() + settings.zoomImageTopOffset,
                    width: imageDim.getWidth() - (settings.zoomImageBorderWidth * 2),
                    zIndex: 1000
                }, settings.zoomContainerCss);
            }
            
            function getCssForZoomImageArea() {
                return $.extend({
                    backgroundColor: "#fff",
                    border: settings.zoomImageAreaBorderWidth + "px solid #ccc",
                    cursor: "pointer",
                    opacity: 0,
                    overflow: "hidden",
                    position: "absolute",
                    zIndex: 2000
                }, settings.zoomAreaContainerCss);
            }
            
            function getZoomAreaImage() {
                if (settings.zoomAreaType.toLowerCase() === "reverse") {
                    var imgSrc = mainImage.getMainImageLink();
                    return $("<img />").attr("src", imgSrc).css({ position: "absolute" });
                }
                
                return "";
            }
            
            function setZoomedImageAreaDimensions(imageDim) {
                $("#" + settings.zoomImageAreaContainerId).css({
                    height: (imageDim.getHeight() / heightRatio),
                    width: (imageDim.getWidth() / widthRatio)
                });
            }
            
            function setZoomedImageAreaPosition(posX, posY, imageDim) {
                var bgX, bgY;
                
                if (settings.zoomAreaType.toLowerCase() === "reverse") {
                    bgX = ((posX - imageDim.left()) * -1) - 1;
                    bgY = ((posY - imageDim.top()) * -1) - 1;
                
                    $(mainImage.getMainImage()).css({ opacity: 0.4 });
                    
                    $("#" + settings.zoomImageAreaContainerId).find("img").css({
                        left: bgX,
                        top: bgY
                    });                    
                } 
                               
                $("#" + settings.zoomImageAreaContainerId).css({
                    left: posX,
                    top: posY
                }).show();                
            }
        },
        
        magipixManager = function (mainImage) {
            var currentImageIndex = 0,
                mainImageObj = new magipixMainImage(mainImage),
                errorBox = new magipixErrorBox(mainImageObj),
                imageGallery = new magipixGalleryImage(mainImageObj),
                largeImage = new magipixLargeImage(mainImageObj),
                loadingBox = new magipixLoadingImage(mainImageObj),
                modal = new magipixModal(),
                zoomImage = new magipixZoomImage(mainImageObj),
                imageDim,
                mainImageWidth,
                mainImageHeight;
            
            function clickOnGalleryImage() {
                zoomImage.setDisabled();
                zoomImage.resetZoom();
                currentImageIndex = $(settings.gallerySelector).index(this);
                imageGallery.animate(currentImageIndex);
                return false; 
            }
            
            function keyDownOnDocument(ev) {
                if (magico.keyboard.isEscape(ev)) { 
                    largeImage.hide(); 
                }
            }
            
            function mouseIsOnMainImage(ev) {
                return (ev.pageX >= imageDim.left() && ev.pageX <= imageDim.left() + mainImageWidth &&
                        ev.pageY >= imageDim.top() && ev.pageY <= imageDim.top() + mainImageHeight);
            }
            
            function mouseMoveBody(ev) {
                if (zoomImage.enabled) {
                    if (mouseIsOnMainImage(ev)) {
                        zoomImage.load(ev, currentImageIndex);
                        zoomImage.positionZoomers(ev);
                    } else {
                        zoomImage.hide();
                    }
                }
            }
            
            function showLargeImage() {
                zoomImage.setDisabled();
                zoomImage.hide();
                largeImage.display(); 
            }
            
            function setImageDimensions() {
                imageDim = new magico.dimensions(mainImage);
                mainImageHeight = imageDim.getHeight();
                mainImageWidth = imageDim.getWidth();            
            }
            
            function setImageGalleryFunctions() {
                imageGallery.afterGalleryImageLoadError = function (error, galleryIndex) {
                    errorBox.display(error, $(settings.gallerySelector).eq(galleryIndex));
                };
            
                imageGallery.afterHide = function () {
                    zoomImage.setEnabled();
                };
            }
            
            function setLargeImageFunctions() {
                largeImage.afterImageChange = function (newIndex) {
                    currentImageIndex = newIndex;
                    zoomImage.resetZoom();
                };
                
                largeImage.afterModalShown = function () {
                    $("#" + settings.modalId).bindOnce("click", function () {
                        largeImage.hide(); 
                        return false; 
                    });
                };
                
                largeImage.afterClosing = function () {
                    if (settings.isModal) {
                        modal.hide();
                    } else {
                        zoomImage.setEnabled();
                        largeImage.remove();
                    }
                    
                    setImageDimensions();
                };
                
                largeImage.afterLargeImageLoadError = function (error) {
                    errorBox.display(error);
                    loadingBox.hide();
                };
                
                largeImage.afterNewLargeImageLoadError = function (error) {
                    errorBox.display(error, $("#" + settings.largeImageId));
                };
                
                largeImage.animateShowModal = function () {
                    modal.animateShow(function () {
                        largeImage.afterModalShown();
                        largeImage.animateToFull();
                    });                
                };
                
                largeImage.beforeAddingToPage = function () {
                    loadingBox.display();
                };
                
                largeImage.beforeAnimateToFull = function () {
                    loadingBox.hide();
                };
                
                largeImage.beforeHideAnimation = function () {
                    errorBox.clearExisting();
                };
                
                largeImage.beforePreloadingNewImage = function (largeImageObj) {
                    loadingBox.display(largeImageObj);
                };
                
                largeImage.beforeSettingNewImage = function () {
                    loadingBox.hide();
                };
            }
            
            function setMainImageFunctions() {
                mainImageObj.afterNewImageLoadError = function (error) {
                    errorBox.display(error);
                };
            }
            
            function setModalFunctions() {
                modal.afterHiding = function () {
                    modal.remove();
                    zoomImage.setEnabled();
                    largeImage.remove();
                };
            }
            
            function setZoomFunctions() {
                zoomImage.afterHide = function () {
                    loadingBox.hide(); 
                };
            
                zoomImage.afterLoad = function () {
                    loadingBox.hide();                          
                };
                
                zoomImage.afterZoomImageLoadError = function (error) {
                    errorBox.display(error);
                };
                
                zoomImage.beforeZoomImageLoad = function () {
                    loadingBox.display();                                      
                };
                
                zoomImage.displayLarge = function () {
                    largeImage.display();
                };
                
                zoomImage.isLargeImageDisplayed = function () {
                    return largeImage.isDisplayed;
                };
            }
            
            /* SETTING EVENT HANDLERS */
            function setClickEvents() {
                $(mainImage).bindOnce("click", function () {
                    showLargeImage();
                    return false;
                });
                
                if (magico.utilities.isNullOrEmpty(settings.viewLargeLinkSelector) === false) {
                    $(settings.viewLargeLinkSelector).bindOnce("click", function () {
                        showLargeImage();
                        return false;
                    });
                }
                
                if (magico.utilities.isNullOrEmpty(settings.gallerySelector) === false) {                
                    $(settings.gallerySelector).bindOnce("click", clickOnGalleryImage);
                }
            }
            
            function setKeyboardEvents() {
                $(document).bindOnce("keydown", keyDownOnDocument);
            }
            
            function setMouseEvents() {
                if (settings.enableZoom) {                
                    $("body").bindOnce("mousemove", mouseMoveBody);
                }
            }
            
            /* INITIALISING MANAGER */
            if (settings.zoomImagePreload) { 
                magico.utilities.preloadImage(zoomImage.getZoomImage(currentImageIndex), function () {}, function () {
                    errorBox.display("Error loading zoom");
                }); 
            }
            
            if (settings.enableEditMode) {
                settings.enableZoom = false;
            }
            
            setImageGalleryFunctions();
            setLargeImageFunctions();
            setModalFunctions();
            setMainImageFunctions();
            setZoomFunctions();
            setImageDimensions();
            setClickEvents();
            setMouseEvents();
            setKeyboardEvents();            
        };
        
        return this.each(function(i, n) {
            var manager = new magipixManager(n);
        });
    };
}(jQuery));
  
/* Magico Basket Code */  
(function (magico) {
    magico.basket = {
        animationSpeed:                         500,
        basketBtnText:                          "Add to Basket",
        basketBtnAddingText:                    "Adding...",
        bulkBasketRowIdAttr:                    "data-order-item",
        bulkProductAddIdAttr:                   "data-id",
        currencySymbol:                         "&euro;",
        currentScrollerPos:                     0,
        defaultPopupWidth:                      0,
        highlightColour:                        "#FBEC5D",
        infoPopupId:                            "magico-basket-popup",
        isMouseDownOnScroll:                    false,
        mouseDownY:                             0,
        overBalanceClass:                       "over-balance",
        popupClass:                             "error-popup",
        popupCloseLinkId:                       "close-popup",
        popupCloseLinkText:                     "Close &raquo;",
        popupInnerBox:                          "inner-box",
        selectorBulkAddToBasket:                ".m_quickQty a",
        selectorBulkAddToBasketQuantity:        ".m_quickQty input",
        selectorBulkAddToBasketPrice:           "h5 strong",
        selectorBulkAddToBasketTitle:           "h3",
        selectorBulkBasket:                     "#m_quickOrder_cart",
        selectorBulkBasketEmptyRow:             "#m_quickOrder_cart table.cart-table-body tr.emptyRow",
        selectorBulkBasketLoadingRow:           "#m_quickOrder_cart table.cart-table-body tr.loading",
        selectorBulkBasketHeader:               "#m_quickOrder_cart table.cart-table-header",
        selectorBulkBasketH3:                   "#m_quickOrder_cart h3",
        selectorBulkBasketItemsInnerContainer:  "#cart-items-container .inner-container",    
        selectorBulkBasketItemsOuterContainer:  "#cart-items-container",
        selectorBulkBasketItemClass:            "basket-item",
        selectorBulkBasketItemInput:            "table.cart-table-body input[name='qty']",
        selectorBulkBasketItemPlus:             "a.quickPlus_lnk",
        selectorBulkBasketItemMinus:            "a.quickMinus_lnk",
        selectorBulkBasketRow:                  "#cart-items-container .inner-container table.cart-table-body tr",
        selectorBulkBasketItemsTable:           "#cart-items-container .inner-container table.cart-table-body",
        selectorBulkBasketItemsTotal:           "#m_quickOrder_cart ul li.bulk-basket-total strong:eq(0)",
        selectorBulkBasketRemaining:            "#m_quickOrder_cart ul li.bulk-basket-remaining strong",
        selectorBulkBasketRemainingBox:         "#m_quickOrder_cart ul li.bulk-basket-remaining",
        selectorBulkBasketRowTemplate:          "#m_quickOrder_cart table.cart-table-body tr.template",
        selectorBulkBasketScroller:             "#cart-item-scroller",
        selectorBulkBasketTotal:                "#m_quickOrder_cart ul li.bulk-basket-total strong:eq(1)",
        selectorBulkBasketTotalBox:             "#m_quickOrder_cart ul li.bulk-basket-total",
        selectorBulkBasketUl:                   "#m_quickOrder_cart ul",
        selectorProductContainerByParent:       "tr",
        selectorProductIdAttr:                  "data-id",
        selectorProductListQtyInBasket:         "h6.msg_inCart_sm span",
        selectorProductListQtyInBasketBox:      "h6.msg_inCart_sm",
        selectorProductQuantity:                "fieldset.m_quickQty input",
        selectorProductPrice:                   "h5 strong",
        selectorProductTitle:                   "h3 a.m_list_TitleLnk",
        selectorProductVariantPrimaryProp:      "input[name^='bizaddtobasketprodpropprim']",
        selectorProductVariantProductId:        "input[id^='bizaddtobasketprod']",
        selectorProductVariantQuantity:         "input[id^='bizaddtobasketqty']",
        selectorProductVariantSecondaryProp:    "input[name^='bizaddtobasketprodpropsec']",
        selectorRemoveBulkBasketItem:           "a.quickRemoveBulk_lnk",
        selectorStandardAddToBasketBtn:         "#m_btn_giant",
        selectorStandardAddProdToBasket:        "#product-added-box",
        selectorStandardAddProdToBasketInner:   "#product-added-box .inner-box",
        selectorStandardAddProdBoxTitle:        "#product-added-box .inner-box strong",
        selectorStandardAddProdBoxPrice:        "#product-added-box .inner-box p",
        selectorStandardBasket:                 "#m_minicart",
        selectorStandardBasketItems:            "#m_minicart h3 strong:eq(0)",
        selectorStandardBasketTotal:            "#m_minicart h3 strong:eq(1)",
        selectorStandardProductTitle:           "#m_prodDetails h1",
        selectorStandardProductPrice:           "#m_prodDetails h2",
        selectorVariantsTableRows:              "table.m_dataTbl tr:not(:first)",
        slideDelay:                             2000,
        webserviceBasketPrimaryPropTitle:       "PrimaryProperty",
        webserviceBasketProductIdTitle:         "ProductID",
        webserviceBasketQuantityTitle:          "Quantity",
        webserviceBasketSecondaryPropTitle:     "SecondaryProperty",
        webserviceMethodAddItem:                "AddToBasket",
        webserviceMethodAddBulkItem:            "AddToBasket",
        webserviceMethodChangeQuantity:         "ChangeItemQuantity",
        webserviceMethodGetItems:               "GetBasket",
        webserviceMethodRemoveItem:             "RemoveItem",
        webserviceUrlBasket:                    "/webservices/basket.asmx/",
        
        initialise: function (options) {
            $.extend(magico.basket, options);
            
            $(this.selectorStandardAddToBasketBtn).unbind("click").click("click", this.clickOnStandardAddToBasket);
            $(this.selectorStandardBasket).stickyBox({ "fixDimensions": true });
            
            this.buildAddProductToBasket();
            this.defaultPopupWidth = $(this.selectorStandardAddProdToBasket).width();
        },
        
        initialiseBulk: function (options) {
            $.extend(magico.basket, options);
        
            $(this.selectorBulkAddToBasket).bindOnce("click", this.clickOnBulkAddToBasketButton);
            $(this.selectorRemoveBulkBasketItem).live("click", this.clickOnRemoveBulkItem);
            $(this.selectorBulkBasketItemPlus).live("click", this.clickOnBulkBasketItemPlus);
            $(this.selectorBulkBasketItemMinus).live("click", this.clickOnBulkBasketItemMinus);
            $(this.selectorBulkBasketItemInput).live("click", this.clickOnBulkBasketItemInput);
            $(this.selectorBulkBasketItemInput).live("keypress", this.keypressOnBulkBasketItemInput);
            $(this.selectorBulkBasketItemsOuterContainer).bindOnce("mouseenter", this.hoverInBulkBasketItems);
            $(this.selectorBulkBasketItemsOuterContainer).bindOnce("mouseleave", this.hoverOutBulkBasketItems);
            $(this.selectorBulkBasketItemsInnerContainer).bindOnce("scroll", this.setBulkBasketScrollerPosition);
            $(this.selectorBulkBasketScroller).bindOnce("mousedown", this.mouseDownOnBulkBasketScroller);
            $("body").bindOnce("mouseup", this.mouseUpOnBody);
            $("body").bindOnce("mousemove", this.mouseMoveOnBody);
            $(window).bindOnce("load", this.checkBulkBasketHeight());
            $(this.selectorBulkBasket).stickyBox();
            
            this.setStyles();
            this.getBasketItems();
            this.autoCorrectBasketRows();
            this.buildPopupHtml();  
        },
        
        addRowsToBulkBasket: function (response, isRowToSlide) {
            var i, basketItem, items;
            
            if (magico.utilities.isNullOrEmpty(response.BasketItems) === false) {
                for (i = 0; i<response.BasketItems.length; i = i+1) {
                    basketItem = response.BasketItems[i];
                    items = $(magico.basket.selectorBulkBasketRow)
                            .filter("[" + magico.basket.bulkBasketRowIdAttr + "='" + basketItem.OrderItemID + "']");
                                
                    if (items.length > 0) {
                        magico.basket.updateBulkBasketItem.call(items[0], basketItem);
                    } else {
                        magico.basket.insertNewRowInBulkBasket(basketItem, isRowToSlide);
                    }
                }
            }
        },
        
        ajaxAddToBasketComplete: function (total, itemCount) {
            magico.basket.slideProductIntoBasket(function () {
                $(magico.basket.selectorStandardBasketItems).text(itemCount);
                $(magico.basket.selectorStandardBasketTotal).html(" " + magico.basket.currencySymbol + total);
                $(magico.basket.selectorStandardAddProdToBasket).hide();                
            });
        },
        
        animateStandardAddToBasket: function () {
            var addToBasketDim = new magico.dimensions(magico.basket.selectorStandardAddToBasketBtn),
                popupDim = new magico.dimensions(magico.basket.selectorStandardAddProdToBasket),
                cartDim = new magico.dimensions(magico.basket.selectorStandardBasket),
                prodTitle = $(magico.basket.selectorStandardProductTitle).text(),
                prodPrice = $(magico.basket.selectorStandardProductPrice).text();

            $(magico.basket.selectorStandardAddProdBoxTitle).html(prodTitle);
            $(magico.basket.selectorStandardAddProdBoxPrice).html(prodPrice);

            $(magico.basket.selectorStandardAddProdToBasket).css({
                "top": addToBasketDim.top() - popupDim.borderTop(),
                "left": addToBasketDim.left() - popupDim.borderLeft(),
                "height": addToBasketDim.getBorderToBorderHeight(),
                "width": addToBasketDim.getBorderToBorderWidth()
            })
            .fadeIn(function () {
                $(magico.basket.selectorStandardAddProdToBasketInner).animate({ 
                    "opacity": 1 
                }, magico.basket.animationSpeed);
            }).animate({
                "top": cartDim.top(),
                "left": cartDim.left() - magico.basket.defaultPopupWidth - 1,
                "height": cartDim.getBorderToBorderHeight() - popupDim.borderTop() - popupDim.borderBottom(),
                "width": magico.basket.defaultPopupWidth
            }, magico.basket.animationSpeed);
        },
        
        autoCorrectBasketRows: function () {
            $(magico.basket.selectorBulkBasketRow)
            .filter(":not(" + magico.basket.selectorBulkBasketRowTemplate + ")")
            .filter(":not(" + magico.basket.selectorBulkBasketEmptyRow + ")")
            .filter(":not(" + magico.basket.selectorBulkBasketLoadingRow + ")")
            .addClass(magico.basket.selectorBulkBasketItemClass);
            
            $(magico.basket.selectorBulkBasketRow).find("input").attr("autocomplete", "off");
        },
        
        buildAddProductToBasket: function () {
            var prodPopupId = magico.basket.selectorStandardAddProdToBasket.replace("#", ""),
                popupHtml ="<div id=\"" + prodPopupId + "\" style=\"display:none\"><div class=\"inner-box\"><strong></strong><p></p></div></div>";
            
            if ($("#" + prodPopupId).length === 0) {
                $("body").append(popupHtml);
            }
        },
        
        buildPopupHtml: function () {
            var popupId = magico.basket.infoPopupId,
                closeBtn = "<a href='#' id='" + magico.basket.popupCloseLinkId + "'>" + magico.basket.popupCloseLinkText + "</a>";
            
            if ($("#" + popupId).length === 0) {
                $("body").append("<div id=\"" + popupId + "\" style=\"display:none\"><div class=\"" + magico.basket.popupInnerBox + "\"></div>" + closeBtn + "</div>");
            }
        },
                
        checkBulkBasketHeight: function () {
            var basketDim = new magico.dimensions(magico.basket.selectorBulkBasket),
                tableH = $(magico.basket.selectorBulkBasketItemsTable).height(),
                containerH = $(magico.basket.selectorBulkBasketItemsInnerContainer).height();
            
            if (basketDim.getHeight() > $(window).height()) {
                $(magico.basket.selectorBulkBasketItemsOuterContainer).css({
                    "overflow": "hidden",
                    "width": basketDim.width()
                });
                
                $(magico.basket.selectorBulkBasketItemsInnerContainer).css({
                    "height": magico.basket.getNewBasketHeight(basketDim),
                    "overflow-x": "hidden",
                    "overflow-y": "auto",
                    "width": basketDim.width() * 2
                });  
            } else if (tableH < containerH) {
                $(magico.basket.selectorBulkBasketItemsInnerContainer).css({
                    "height": "auto",
                    "overflow": "auto"
                });  
            }    
        },
        
        checkBulkBasketScrollerVisibility: function () {
            if (magico.basket.hasBulkBasketOverflow()) {
                magico.basket.setBulkBasketScrollerVisibility(true);
            } else {
                magico.basket.setBulkBasketScrollerVisibility(false);
            }
        },
        
        checkBulkBasketTotal: function () {
            var visibleRows = $(magico.basket.selectorBulkBasketItemsTable)
                              .find("tr." + magico.basket.selectorBulkBasketItemClass);
                              
            if (visibleRows.length === 0) {
                $(magico.basket.selectorBulkBasketEmptyRow).slideDownRow(magico.basket.animationSpeed);
            }
        },
        
        clickOnBulkAddToBasketButton: function (ev) {
            var thisClick = this,
                addRequest = magico.basket.getNewItemsForBulkBasket(new magico.ajax.data(), thisClick);
                
            magico.ajax.request({
                url: magico.basket.webserviceUrlBasket + magico.basket.webserviceMethodAddBulkItem, 
                data: addRequest,
                presend: function () {
                    magico.utilities.setCursorWaiting.call(thisClick);
                },
                success: function (response) {
                    magico.utilities.removeCursorWaiting.call(thisClick);
                    
                    if (response.IsSuccessful) {
                        magico.basket.addRowsToBulkBasket(response, true);
                        magico.basket.setBulkBasketTotals(response);
                    }
                    
                    if (magico.utilities.isNullOrEmpty(response.StatusMessage) === false) {
                        magico.basket.showErrorPopup(magico.basket.getErrorMessage(response.StatusMessage));
                    }
                },
                error: function (responseXhr, responseStatus, responseError) {
                    magico.utilities.removeCursorWaiting.call(thisClick);
                    magico.basket.showErrorPopup(magico.basket.getErrorMessage(responseError));
                }
            });

            return false;
        },
        
        clickOnBulkBasketItemInput: function (ev) {
            $(this).val("");
        },
        
        clickOnBulkBasketItemPlus: function () {
            var currentVal = parseInt($(this).siblings("input").val(), 10), newVal = currentVal + 1;
            return magico.basket.setBulkBasketItemQuantity($(this).siblings("input"), newVal, this);
        },
        
        clickOnBulkBasketItemMinus: function () {
            var currentVal = parseInt($(this).siblings("input").val(), 10), newVal = currentVal - 1;
            
            if (newVal > 0) {            
                return magico.basket.setBulkBasketItemQuantity($(this).siblings("input"), newVal, this);
            } else {
                return magico.basket.removeBulkItem(this);
            }
        },
        
        clickOnRemoveBulkItem: function () {            
            return magico.basket.removeBulkItem(this);
        },
        
        clickOnStandardAddToBasket: function () {
            var addRequest = magico.basket.getNewItemsForBasket(new magico.ajax.data());
            
            magico.ajax.request({
                url: magico.basket.webserviceUrlBasket + magico.basket.webserviceMethodAddItem, 
                data: addRequest,
                presend: function () {
                    magico.basket.setStandardAddToBasketButtonText(magico.basket.basketBtnAddingText);
                    magico.basket.animateStandardAddToBasket();
                },
                success: function (response) {
                    if (response.IsSuccessful) {
                        setTimeout(function () {
                            magico.basket.ajaxAddToBasketComplete(response.BasketTotal, response.ItemsTotal);
                        }, magico.basket.slideDelay);
                    } else {
                        $(magico.basket.selectorStandardAddProdToBasket).hide();    
                    }
                    
                    magico.basket.resetStandardAddToBasketButton();                
                },
                error: function (responseXhr, responseStatus, responseError) {
                    magico.basket.resetStandardAddToBasketButton();
                }
            });
            
            return false;
        },
        
        getBasketItems: function () {
            var getRequest = new magico.ajax.data(),
                ajaxReq;            
            
            magico.ajax.request({
                url: magico.basket.webserviceUrlBasket + magico.basket.webserviceMethodGetItems, 
                data: getRequest,
                success: function (response) {
                    $(magico.basket.selectorBulkBasketLoadingRow).remove();
                    
                    if (response.IsSuccessful) {
                        magico.basket.addRowsToBulkBasket(response, false);
                        magico.basket.setBulkBasketTotals(response);
                        magico.basket.checkBulkBasketTotal();
                        $(magico.basket.selectorBulkBasketTotalBox).show();
                        $(magico.basket.selectorBulkBasketRemainingBox).show();
                    }
                }
            });
        },
              
        getBulkBasketItemValues: function (thisClick) {
            this.parentRow = $(thisClick).parents(magico.basket.selectorProductContainerByParent);
            this.id = this.parentRow.attr(magico.basket.selectorProductIdAttr);
            this.title = this.parentRow.find(magico.basket.selectorProductTitle).html();
            this.price = this.parentRow.find(magico.basket.selectorProductPrice).html();
            this.quantity = this.parentRow.find(magico.basket.selectorProductQuantity).val();
            
            return this;
        },
        
        getErrorMessage: function (errorMsg) {
            var errorMsg = "<p><strong>The following error occurred:</strong></p><p>" + errorMsg + "</p>";            
        },
        
        getExistingItemInBulkBasket: function (changeRequest, thisInput, qty) {
            var bulkItemRow = $(thisInput).parents(magico.basket.selectorBulkBasketRow),
                productId = bulkItemRow.attr(magico.basket.bulkBasketRowIdAttr);
            
            if (typeof changeRequest.request.BasketItems === "undefined") {
                changeRequest.request.BasketItems = [];
            }
            
            changeRequest.request.BasketItems.push({
                "Quantity": qty,
                "ProductId": productId
            });
            
            return changeRequest;
        },        
        
        getNewBasketHeight: function (basketDim) {
            var newBasketHeight = $(window).height(),
                h3Dim = new magico.dimensions(magico.basket.selectorBulkBasketH3),
                headerDim = new magico.dimensions(magico.basket.selectorBulkBasketHeader),
                ulDim = new magico.dimensions(magico.basket.selectorBulkBasketUl);
                
            return newBasketHeight - basketDim.getExtraHeights() - h3Dim.getHeight() - headerDim.getHeight() - ulDim.getHeight();
        },
        
        getNewItemsForBasket: function (addRequest) {
            $(magico.basket.selectorVariantsTableRows).each(function (i, n) {
                var quantity = magico.utilities.getVal($(n).find(magico.basket.selectorProductVariantQuantity)),
                    productId = magico.utilities.getVal($(n).find(magico.basket.selectorProductVariantProductId)),
                    primaryProp = magico.utilities.getVal($(n).find(magico.basket.selectorProductVariantPrimaryProp)),
                    secondaryProp = magico.utilities.getVal($(n).find(magico.basket.selectorProductVariantSecondaryProp)),
                    iQty = parseInt(quantity, 10);
                
                if (isNaN(iQty) === false && iQty > 0) {
                    addRequest.request.BasketItems.push({
                        "Quantity": quantity,
                        "ProductId": productId,
                        "PrimaryProperty": primaryProp,
                        "SecondaryProperty": secondaryProp
                    });
                }
            });
            
            return addRequest;
        },
        
        getNewItemsForBulkBasket: function (addRequest, thisClick) {
            var bulkItemRow = $(thisClick).parents(magico.basket.selectorProductContainerByParent),
                quantity = magico.utilities.getVal(bulkItemRow.find(magico.basket.selectorBulkAddToBasketQuantity)),
                productId = bulkItemRow.attr(magico.basket.bulkProductAddIdAttr),
                iQty = parseInt(quantity, 10);
            
            if (typeof addRequest.request.BasketItems === "undefined") {
                addRequest.request.BasketItems = [];
            }
            
            if (isNaN(iQty) === false && iQty > 0) {
                addRequest.request.BasketItems.push({
                    "Quantity": quantity,
                    "ProductId": productId
                });
            }
            
            return addRequest;
        },        
        
        getTemplateClone: function () {
            return $(magico.basket.selectorBulkBasketRowTemplate).clone().removeAttr("class");
        },
        
        hasBulkBasketOverflow: function () {
            var tableH = $(magico.basket.selectorBulkBasketItemsTable).height(),
                containerH = $(magico.basket.selectorBulkBasketItemsInnerContainer).height();
                
            return tableH > containerH;
        },
        
        hoverInBulkBasketItems: function () {
            if (magico.basket.hasBulkBasketOverflow()) {
                magico.basket.setBulkBasketScrollerHeight();
                magico.basket.setBulkBasketScrollerVisibility(true);
            }
        },
        
        hoverOutBulkBasketItems: function () {
            magico.basket.setBulkBasketScrollerVisibility(false);
        },
        
        insertNewRowInBulkBasket: function (basketItem, isRowToSlide) {
            var newRow = magico.basket.getTemplateClone();
                
            newRow.attr(magico.basket.bulkBasketRowIdAttr, basketItem.OrderItemID).css("display", "none");
            newRow.attr("class", magico.basket.selectorBulkBasketItemClass);
            newRow.find("td:eq(0) input").val(basketItem.Quantity);
            newRow.find("td:eq(1) p").html(basketItem.Title);
            newRow.children("td:eq(2)").html(magico.utilities.roundNumber(basketItem.Price));
            
            if (magico.utilities.isNullOrEmpty(isRowToSlide)) {
                isRowToSlide = true;
            }
            
            if (isRowToSlide) {
                $(magico.basket.selectorBulkBasketEmptyRow).slideUpRow(magico.basket.animationSpeed, function () {
                    $(magico.basket.selectorBulkBasketItemsTable).prepend(newRow);
                    $(magico.basket.selectorBulkBasketItemsInnerContainer).scrollTop(0);
                    
                    newRow.slideDownRow(magico.basket.animationSpeed, magico.basket.checkBulkBasketHeight);
                });
            } else {
                $(magico.basket.selectorBulkBasketEmptyRow).hide(1, function () {
                    $(magico.basket.selectorBulkBasketItemsTable).prepend(newRow);
                    $(magico.basket.selectorBulkBasketItemsInnerContainer).scrollTop(0);
                    
                    newRow.show(1, magico.basket.checkBulkBasketHeight);
                });
            }
            
            magico.basket.updateProductQuantityInBasket(basketItem); 
        },
        
        isBasketItemOutOfView: function () {
            var innerContDim = new magico.dimensions(magico.basket.selectorBulkBasketItemsInnerContainer),
                itemDim = new magico.dimensions(this);
        
            return (((innerContDim.top() + innerContDim.getHeight()) <= itemDim.top()) ||
                   (innerContDim.top() >= itemDim.top()));
        },
        
        keypressOnBulkBasketItemInput: function (ev) {
            if (magico.keyboard.isEnter(ev)) {
                magico.basket.setBulkBasketItemQuantity($(this), parseInt($(this).val(), 10), this);
            }
        },
        
        mouseDownOnBulkBasketScroller: function (ev) {
            magico.basket.isMouseDownOnScroll = true;
            magico.basket.currentScrollerPos = $(magico.basket.selectorBulkBasketScroller).offset().top - 
                                               $(magico.basket.selectorBulkBasketItemsInnerContainer).offset().top;
            magico.basket.mouseDownY = ev.pageY;
        },
        
        mouseMoveOnBody: function (ev) {
            if (magico.basket.isMouseDownOnScroll) {
                var scrollTop = ev.pageY - magico.basket.mouseDownY + magico.basket.currentScrollerPos;
                magico.basket.setBulkBasketScrollerTop(scrollTop, true);
            }
        },
        
        mouseUpOnBody: function () { 
            magico.basket.isMouseDownOnScroll = false; 
        },
        
        refreshProductQuantitiesInBasket: function (allItems) {
            var allHighlightedProducts = $(magico.basket.selectorProductListQtyInBasketBox).filter(":visible"),
                allProductIds = [];
        
            $(allHighlightedProducts).each(function (i, n) {
                var parent = $(n).parents(magico.basket.selectorProductContainerByParent);
                allProductIds.push(parent.attr(magico.basket.bulkProductAddIdAttr));
            });
        
            $(allItems).each(function (i, n) {
                var inArrayIndex = $.inArray(n.ProductID, allProductIds);
                if (inArrayIndex > -1) {
                    allProductIds.remove(inArrayIndex);
                }
            });
        
            $(allProductIds).each(function (i, n) {
                var productRow = $("[" + magico.basket.bulkProductAddIdAttr + "='" + n + "']");
                $(magico.basket.selectorProductListQtyInBasketBox, productRow).fadeOut();
            });
        },
        
        removeBulkItem: function(thisClick) {
            var removeRequest = new magico.ajax.data(),
                ajaxReq;            
                
            magico.basket.getExistingItemInBulkBasket(removeRequest, thisClick, 0);
            
            magico.ajax.request({
                url: magico.basket.webserviceUrlBasket + magico.basket.webserviceMethodRemoveItem, 
                data: removeRequest,
                presend: function () {
                    magico.utilities.setCursorWaiting.call(thisClick);   
                },
                success: function (response) {
                    if (response.IsSuccessful) {
                        var $selRow = $(thisClick).parents("tr");
                            
                        $selRow.slideUpRow(magico.basket.animationSpeed, function () {
                            $selRow.remove();
                            magico.basket.checkBulkBasketHeight();
                            magico.basket.checkBulkBasketScrollerVisibility();
                            magico.basket.checkBulkBasketTotal();
                            magico.basket.setBulkBasketScrollerHeight();
                            magico.basket.setBulkBasketScrollerPosition();
                            magico.basket.setBulkBasketTotals(response);
                        });
                        
                        magico.basket.refreshProductQuantitiesInBasket(response.BasketItems);
                    }

                    magico.utilities.removeCursorWaiting.call(thisClick);            
                },
                error: function (respXhr, respStatus, respError) {
                    magico.utilities.removeCursorWaiting.call(thisClick);            
                }
            });
            
            return false;          
        },
        
        resetStandardAddToBasketButton: function () {
            magico.basket.setStandardAddToBasketButtonText(magico.basket.basketBtnText);
        },
        
        setBulkBasketItemInView: function () {
            var innerContDim = new magico.dimensions(magico.basket.selectorBulkBasketItemsInnerContainer),
                itemDim = new magico.dimensions(this),
                newScrollTop = ((itemDim.positionTop() - innerContDim.getHeight()) + itemDim.getHeight() + innerContDim.scrollTop());
                
            if (newScrollTop < 0) {
                newScrollTop = 0; 
            }
            
            $(magico.basket.selectorBulkBasketItemsInnerContainer).scrollTop(newScrollTop);
        },
        
        setBulkBasketItemQuantity: function ($input, newVal, thisClickedElement) {
            if (newVal < 0) { newVal = 0; }

            var changeRequest = new magico.ajax.data(),
                ajaxReq;
                 
            magico.basket.getExistingItemInBulkBasket(changeRequest, $input, newVal);
            
            magico.ajax.request({
                url: magico.basket.webserviceUrlBasket + magico.basket.webserviceMethodChangeQuantity, 
                data: changeRequest,
                presend: function () {
                    magico.utilities.setCursorWaiting.call(thisClickedElement);            
                },
                success: function (response) {
                    if (response.IsSuccessful) {
                        $input.val(newVal);
                        magico.basket.setBulkBasketTotals(response);                    
                    }
                    
                    magico.utilities.removeCursorWaiting.call(thisClickedElement);            
                },
                error: function (respXhr, respStatus, respError) {
                    magico.utilities.removeCursorWaiting.call(thisClickedElement);            
                }
            });
            
            return false;
        },
                    
        setBulkBasketScrollerVisibility: function (setVisible) {
            if (setVisible) {
                $(magico.basket.selectorBulkBasketScroller).fadeIn();
            } else {
                $(magico.basket.selectorBulkBasketScroller).fadeOut();
            }
        },  
        
        setBulkBasketScrollerHeight: function () {
            var outerBoxHeight = parseFloat($(magico.basket.selectorBulkBasketItemsOuterContainer).height()),
                innerBoxHeight = parseFloat($(magico.basket.selectorBulkBasketItemsTable).height()),
                percentage = parseFloat((outerBoxHeight / innerBoxHeight));
                
            $(magico.basket.selectorBulkBasketScroller).css("height", (percentage * outerBoxHeight));
        },
        
        setBulkBasketScrollerPosition: function () {
            var innerContScrollTop = $(magico.basket.selectorBulkBasketItemsInnerContainer).scrollTop(),
                tableH = $(magico.basket.selectorBulkBasketItemsTable).height(),
                containerH = $(magico.basket.selectorBulkBasketItemsInnerContainer).height(),
                percentScrolled = innerContScrollTop / tableH,
                scrollTop = percentScrolled * containerH;
          
            magico.basket.setBulkBasketScrollerTop(scrollTop);  
        },
        
        setBulkBasketScrollerTop: function (newTop, scrollTable) {
            if (newTop < 0) { 
                newTop = 0; 
            } else {
                var containerH = $(magico.basket.selectorBulkBasketItemsInnerContainer).height(),
                    scrollerH = $(magico.basket.selectorBulkBasketScroller).height(),
                    maxTop = (containerH - scrollerH);
            
                if (newTop > maxTop) {
                    newTop = maxTop;
                }
            }
            
            $(magico.basket.selectorBulkBasketScroller).css("top", newTop);
            
            if (scrollTable) {
                magico.basket.setBulkBasketTableScrollTop(newTop);
            }
        },
        
        setBulkBasketTableScrollTop: function (scrollerTop) {
            var tableH = $(magico.basket.selectorBulkBasketItemsTable).height(),
                containerH = $(magico.basket.selectorBulkBasketItemsInnerContainer).height(),
                percentageMoved = scrollerTop / containerH,
                newScrollTop = tableH * percentageMoved;
                
            $(magico.basket.selectorBulkBasketItemsInnerContainer).scrollTop(newScrollTop);
        },
        
        setBulkBasketTotals: function (response) {
            /* Setting the totals in the movable bulk basket */
            var basketTotal = magico.utilities.roundNumber(response.BasketTotal),
                balanceRemaining = magico.utilities.roundNumber(response.BalanceRemaining);
            
            $(magico.basket.selectorBulkBasketTotal).html(magico.basket.currencySymbol + basketTotal);
            $(magico.basket.selectorBulkBasketItemsTotal).text(response.ItemsTotal);                    
            $(magico.basket.selectorBulkBasketRemaining).html(magico.basket.currencySymbol + balanceRemaining);
            
            if (parseFloat(response.BalanceRemaining) < 0) {
                $(magico.basket.selectorBulkBasketRemainingBox).addClass(magico.basket.overBalanceClass);
            } else {
                $(magico.basket.selectorBulkBasketRemainingBox).removeClass(magico.basket.overBalanceClass);
            }
            
            /* Setting the totals in the basket in the header */
            $(magico.basket.selectorStandardBasket).animate({ "opacity": 0}, magico.animationSpeed, function () {
                $(magico.basket.selectorStandardBasketTotal).html(magico.basket.currencySymbol + basketTotal);
                $(magico.basket.selectorStandardBasketItems).text(response.ItemsTotal);
                
                $(this).animate({ "opacity": 1 }, magico.basket.animationSpeed);
            });
            
            magico.basket.updateProductQuantityInBasket(response.BasketItems); 
        },
        
        setStandardAddToBasketButtonText: function (newText) {
            $(magico.basket.selectorStandardAddToBasketBtn).html(newText);            
        },
        
        setStyles: function () {
            
        },
        
        showErrorPopup: function (errorMsg) {
            $("#" + magico.basket.infoPopupId + " ." + magico.basket.popupInnerBox)
            .html(errorMsg)
            .parent()
            .addClass(magico.basket.popupClass)
            .magiPopup({ popupCloseSelector: "#" + magico.basket.popupCloseLinkId });        
        },
        
        slideProductIntoBasket: function (funcAfterSlide) {
            var cartDim = new magico.dimensions(magico.basket.selectorStandardBasket);
            
            $(magico.basket.selectorStandardAddProdToBasket).animate({
                "left": cartDim.left(),
                "width": 0
            }, magico.basket.animationSpeed, function () {
                if (magico.utilities.isFunction(funcAfterSlide)) {
                    funcAfterSlide.call();
                }
            });
        },
        
        updateBulkBasketItem: function (basketItemFromServer) {
            var itemQtyEl = $(this).find("td:eq(0) input");
        
            if (parseFloat($(itemQtyEl).val()) !== basketItemFromServer.Quantity) {
                if (magico.basket.isBasketItemOutOfView.call(this)) {
                    magico.basket.setBulkBasketItemInView.call(this);
                }
            
                magico.animation.backgroundHighlight($(this).find("td"), magico.basket.highlightColour, magico.basket.animationSpeed);
                $(itemQtyEl).val(basketItemFromServer.Quantity);
            }
            
            $(this).find("td:eq(1) p").html(basketItemFromServer.Title);
            $(this).children("td:eq(2)").html(magico.utilities.roundNumber(basketItemFromServer.Price));
            magico.basket.updateProductQuantityInBasket(basketItemFromServer); 
        },
        
        updateProductQuantityInBasket: function (basketItems) {
            $(basketItems).each(function (i, basketItem) {
                $("[" + magico.basket.bulkProductAddIdAttr + "='" + basketItem.ProductID + "']").each(function(j, n) {
                    if (basketItem.Quantity > 0) {
                        $(magico.basket.selectorProductListQtyInBasket, n).text(basketItem.Quantity);
                        $(magico.basket.selectorProductListQtyInBasketBox, n).fadeIn();
                    } else {
                        $(magico.basket.selectorProductListQtyInBasketBox, n).fadeOut();
                    }
                });
                
            });
        }
    };
}(magico));

/* Magico Ticketing Code */
(function (magico) {
    magico.tickets = {
        animationSpeed:                     500,
        classNameErrorFieldset:             "su_negMsg",
        otherCategoryId:                    "",
        selectorAllFormInputs:              "#m_form fieldset input, #m_form fieldset textarea, #m_form fieldset select",
        selectorAllNegMsgs:                 "fieldset .negMsg",
        selectorCategories:                 "select#mbf_Title",
        selectorContactFormEmailInput:      "#m_form fieldset .email-validation",
        selectorContactFormStandardInput:   "#m_form fieldset .std-validation",
        selectorEmail:                      "input#mbf_Email",
        selectorErrorSummary:               "div.su_negMsg",
        selectorFirstName:                  "input#mbf_FirstName",
        selectorForm:                       "div#m_form",
        selectorGeneralError:               "#general-ticket-error",
        selectorLastName:                   "input#mbf_LastName",
        selectorOrderNumber:                "input#mbf_OrderNo",
        selectorOtherTitle:                 "input#mbf_Other",
        selectorPhone:                      "input#mbf_Phone",
        selectorMessage:                    "textarea#mbf_Message",
        selectorNegMsg:                     ".negMsg",
        selectorPosMsg:                     ".posMsg",
        selectorSendAnother:                "#send-another",
        selectorSendTicketBtn:              "a#send-message",
        selectorSuccessMessage:             "div#m_form_success",
        webserviceUrl:                      "/webservices/tickets.asmx/",
        
        initialise: function (options) {
            $.extend(magico.tickets, options);
        
            $(this.selectorSendTicketBtn).bindOnce("click", this.sendTicket);
            $(this.selectorContactFormStandardInput).bindOnce("blur", this.validateStandardInput);
            $(this.selectorContactFormEmailInput).bindOnce("blur", this.validateEmailInput);
            $(this.selectorSendAnother).bindOnce("click", this.showContactForm);
        },
        
        teardown: function () {
            $(this.selectorSendTicketBtn).unbind("click");
            $(this.selectorContactFormStandardInput).unbind("blur");
            $(this.selectorContactFormEmailInput).unbind("blur");
            $(this.selectorSendAnother).unbind("click");
        },
        
        getCategoryTitleSelector: function (categoryId) {
            return magico.tickets.selectorCategories + " option[value='" + categoryId + "']";
        },
        
        getSendTicketRequestParams: function () {
            var data = new magico.ajax.data();
            
            data.request.CategoryID = magico.utilities.getVal(magico.tickets.selectorCategories);
            data.request.OrderNumber = magico.utilities.getVal(magico.tickets.selectorOrderNumber);
            data.request.Title = $(magico.tickets.getCategoryTitleSelector(data.request.TicketCategoryID)).html();
            data.request.Message = magico.utilities.getVal(magico.tickets.selectorMessage);
            data.request.EmailAddress = magico.utilities.getVal(magico.tickets.selectorEmail);
            data.request.FirstName = magico.utilities.getVal(magico.tickets.selectorFirstName);
            data.request.LastName = magico.utilities.getVal(magico.tickets.selectorLastName);
            data.request.PhoneNumber = magico.utilities.getVal(magico.tickets.selectorPhone);           
            
            if (data.request.CategoryID === magico.tickets.otherCategoryId) {
                data.request.Title = magico.utilities.getVal(magico.tickets.selectorOtherTitle);
            }
            
            return data;
        },
        
        hideErrorSummary: function () {
            $(magico.tickets.selectorErrorSummary).hide();
        },
        
        hideValidationError: function () {
            $(this)
            .siblings(magico.tickets.selectorNegMsg)
            .hide()
            .siblings(magico.tickets.selectorPosMsg)
            .show()
            .parent()
            .removeClass(magico.tickets.classNameErrorFieldset);
        },
        
        isFormValid: function () {
            $(magico.tickets.selectorAllFormInputs).each(function (i, n) {
                $(n).focus().blur();    
            });
            
            if ($(magico.tickets.selectorAllNegMsgs).filter(":visible").length > 0) {
                magico.tickets.showErrorSummary();
                return false;
            }
            
            magico.tickets.hideErrorSummary();
            return true;
        },
        
        sendTicket: function () {
            if (magico.tickets.isFormValid()) {
                var thisClick = this;
                
                magico.ajax.request({
                    url: magico.tickets.webserviceUrl + "Send", 
                    data: magico.tickets.getSendTicketRequestParams(),
                    presend: function () {
                        magico.utilities.setCursorWaiting.call(thisClick);
                    },
                    success: function (response) {
                        if (response.IsSuccessful) {
                            $(magico.tickets.selectorGeneralError).hide();
                            magico.tickets.showSuccessMessage();
                        } else {
                            magico.tickets.showGeneralError(response.StatusMessage);
                        }
                        
                        magico.utilities.removeCursorWaiting.call(thisClick);            
                    },
                    error: function (respXhr, respStatus, respError) {
                        magico.utilities.removeCursorWaiting.call(thisClick);            
                        magico.tickets.showGeneralError(respError);
                    }
                });
            }
            
            return false;
        },
        
        showContactForm: function () {
            $(magico.tickets.selectorAllFormInputs).val("");
            $(magico.tickets.selectorNegMsg).add(magico.tickets.selectorPosMsg).hide();
            $(magico.tickets.selectorForm).slideDown().siblings(magico.tickets.selectorSuccessMessage).hide();
            $(magico.tickets.selectorSendTicketBtn).show();
        },
        
        showErrorSummary: function () {
            $(magico.tickets.selectorErrorSummary).slideDown();
        },
        
        showGeneralError: function (errorMsg) {
            $(magico.tickets.selectorGeneralError).children().remove().end().append("<p>" + errorMsg + "</p>").show();
        },
        
        showSuccessMessage: function () {
            $(magico.tickets.selectorForm).slideUp(magico.tickets.animationSpeed)
            .siblings(magico.tickets.selectorSuccessMessage).slideDown(magico.tickets.animationSpeed);
            
            $(magico.tickets.selectorSendTicketBtn).hide();            
        },
        
        showValidationError: function () {
            $(this)
            .siblings(magico.tickets.selectorPosMsg)
            .hide()
            .siblings(magico.tickets.selectorNegMsg)
            .show()
            .parent()
            .addClass(magico.tickets.classNameErrorFieldset);
        },
        
        validateEmailInput: function () {
            var email = $(this).val();
            
            if (magico.validation.isValidEmail(email)) { 
                magico.tickets.hideValidationError.call(this);
            } else { 
                magico.tickets.showValidationError.call(this);
            }
        },
        
        validateStandardInput: function () {
            if ($(this).val() === "") {
                magico.tickets.showValidationError.call(this);
            } else {
                magico.tickets.hideValidationError.call(this);
            }
        }
    };
}(magico));


