/**
 * Medusa for Magento 1.5.1.0
 * Design and Development by creative-d2 design&development (http://www.creative-d2.de)
 * Distributed by ThemeForest (http://themeforest.net)
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade Magento to newer
 * versions in the future. If you wish to customize Magento for your
 * needs please refer to http://www.magentocommerce.com for more information.
 *
 * @author     Ömer Bildirici jun.
 * @package    medusa_default
 * @copyright  Copyright 2011 Ömer Bildirici jun. (http://www.creative-d2.de)
 * @license    All rights reserved.
 * @version    1.0.1
 */

(function($) {
    $.fn.exSlider = function(params) {

        var EFFECTS = new Array(9);
        EFFECTS["fade"] = 0;
        EFFECTS["vertical.tile"] = 1;
        EFFECTS["fade.left"] = 2;
        EFFECTS["fade.right"] = 3;
        EFFECTS["horizontal.tile"] = 4;
        EFFECTS["fade.top"] = 5;
        EFFECTS["fade.bottom"] = 6;
        EFFECTS["none"] = 7;
        EFFECTS["random"] = 8;

        var DEFAULT_DELAY = 2500;
        var DURATION = 500;
        var ANIMATE_SPEED = 750;
        var UPDATE_TEXT = "updatetext";

        var TEXT_EFFECTS = new Array(4);
        TEXT_EFFECTS["fade"] = 0;
        TEXT_EFFECTS["down"] = 1;
        TEXT_EFFECTS["right"] = 2;
        TEXT_EFFECTS["none"] = 3;

        var BOTTOM_LEFT = "BLEFT";
        var BOTTOM_RIGHT = "BRIGHT";
        var BOTTOM_CENTER = "BCENTER";
        var INSIDE = "inside";

        //Vertical Stripes
        function VerticalStripes(slider, areaWidth, areaHeight, stripeSize, bgColor, duration, delay) {
            var $stripes;
            var $arr;
            var total;
            var intervalId = null;

            //init stripes
            var init = function() {
                total = Math.ceil(areaWidth / stripeSize);
                var divs = "";
                for (var i = 0; i < total; i++) {
                    divs += "<div class='vcpiece' id='" + i + "'></div>";
                }
                slider.addToScreen(divs);

                $stripes = $("div.vcpiece", slider.$el);
                $arr = new Array(total);
                $stripes.each(function(n) {
                    $(this).css({
                        left: (n * stripeSize),
                        height: areaHeight
                    });
                    $arr[n] = $(this);
                });
            };

            //clear animation
            this.clear = function() {
                clearInterval(intervalId);
                $stripes.stop(true).css({
                    "z-index": 2,
                    opacity: 0
                });
            };

            //display content
            this.displayContent = function($img, effect) {
                setPieces($img, effect);
                if (effect == EFFECTS["vert.random.fade"]) {
                    animateRandom($img);
                } else {
                    animate($img, effect);
                }
            };

            //set image stripes
            var setPieces = function($img, effect) {
                switch (effect) {
                case EFFECTS["vertical.tile"]:
                    setVertPieces($img, -areaHeight, 1, stripeSize, false);
                    break;
                default:
                    setVertPieces($img, 0, 0, stripeSize, false);
                	break;
                }
            };

            //set vertical stripes
            var setVertPieces = function($img, topPos, opacity, width, alt) {
                var imgSrc = $img.attr("src");
                var tOffset = 0;
                var lOffset = 0;
                if (slider.centerImg()) {
                    tOffset = (areaHeight - $img.height()) / 2;
                    lOffset = (areaWidth - $img.width()) / 2;
                }
                $stripes.each(function(n) {
                    var xPos = (( - n * stripeSize) + lOffset);
                    if (alt) {
                        topPos = (n % 2) === 0 ? -areaHeight: areaHeight;
                    }
                    $(this).css({
                        background: bgColor + " url('" + imgSrc + "') no-repeat",
                        backgroundPosition: xPos + "px " + tOffset + "px",
                        opacity: opacity,
                        top: topPos,
                        width: width,
                        "z-index": 3
                    });
                });
            };

            //animate stripes			
            var animate = function($img, effect) {
                var start,
                end,
                incr,
                limit;
                switch (effect) {
                case EFFECTS["vertical.tile"]:
                case EFFECTS["fade.left"]:
                    start = 0;
                    end = total - 1;
                    incr = 1;
                    break;
                default:
                    start = total - 1;
                    end = 0;
                    incr = -1;
                    break;
                }

                intervalId = setInterval(function() {
                    $($stripes.get(start)).animate({
                        top: 0,
                        opacity: 1,
                        width: stripeSize
                    }, duration, "", function() {
                        if ($(this).attr("id") == end) {
                            slider.setComplete($img);
                        }
                    });
                    if (start == end) {
                        clearInterval(intervalId);
                    }
                    start += incr;
                }, delay);
            };

            //animate random fade 
            var animateRandom = function($img) {
                shuffleArray($arr);
                var i = 0;
                var count = 0;
                intervalId = setInterval(function() {
                    $arr[i++].animate({
                        opacity: 1
                    }, duration, "", function() {
                        if (++count == total) {
                            slider.setComplete($img);
                        }
                    });
                    if (i == total) {
                        clearInterval(intervalId);
                    }
                }, delay);
            };

            init();
        }

        //Horizontal Stripes
        function HorizontalStripes(slider, areaWidth, areaHeight, stripeSize, bgColor, duration, delay) {
            var $stripes;
            var $arr;
            var total;
            var intervalId = null;

            //init stripes
            var init = function() {
                total = Math.ceil(areaHeight / stripeSize);
                var divs = "";
                for (var j = 0; j < total; j++) {
                    divs += "<div class='hzpiece' id='" + j + "'><!-- --></div>";
                }
                slider.addToScreen(divs);

                $stripes = $("div.hzpiece", slider.$el);
                $arr = new Array(total);
                $stripes.each(function(n) {
                    $(this).css({
                        top: (n * stripeSize),
                        width: areaWidth
                    });
                    $arr[n] = $(this);
                });
            };

            //clear animation
            this.clear = function() {
                clearInterval(intervalId);
                $stripes.stop(true).css({
                    "z-index": 2,
                    opacity: 0
                });
            };

            //display content
            this.displayContent = function($img, effect) {
                setPieces($img, effect);
                if (effect == EFFECTS["horz.random.fade"]) {
                    animateRandom($img);
                } else {
                    animate($img, effect);
                }
            };

            //set image stripes
            var setPieces = function($img, effect) {
                switch (effect) {
                case EFFECTS["horizontal.tile"]:
                    setHorzPieces($img, -areaWidth, 1, stripeSize, false);
                    break;
                default:
                    setHorzPieces($img, 0, 0, stripeSize, false);
                	break;
                }
            };

            //set horizontal stripes
            var setHorzPieces = function($img, leftPos, opacity, height, alt) {
                var imgSrc = $img.attr("src");
                var tOffset = 0;
                var lOffset = 0;
                if (slider.centerImg()) {
                    tOffset = (areaHeight - $img.height()) / 2;
                    lOffset = (areaWidth - $img.width()) / 2;
                }
                $stripes.each(function(n) {
                    var yPos = (( - n * stripeSize) + tOffset);
                    if (alt) {
                        leftPos = (n % 2) === 0 ? -areaWidth: areaWidth;
                    }
                    $(this).css({
                        background: bgColor + " url('" + imgSrc + "') no-repeat",
                        backgroundPosition: lOffset + "px " + yPos + "px",
                        opacity: opacity,
                        left: leftPos,
                        height: height,
                        "z-index": 3
                    });
                });
            };

            //animate stripes			
            var animate = function($img, effect) {
                var start,
                end,
                incr;
                switch (effect) {
                case EFFECTS["horizontal.tile"]:
                case EFFECTS["fade.top"]:
                    start = 0;
                    end = total - 1;
                    incr = 1;
                    break;
                default:
                    start = total - 1;
                    end = 0;
                    incr = -1;
                    break;
                }

                intervalId = setInterval(function() {
                    $($stripes.get(start)).animate({
                        left: 0,
                        opacity: 1,
                        height: stripeSize
                    }, duration, "", function() {
                        if ($(this).attr("id") == end) {
                            slider.setComplete($img);
                        }
                    });
                    if (start == end) {
                        clearInterval(intervalId);
                    }
                    start += incr;
                }, delay);
            };

            //animate random fade 
            var animateRandom = function($img) {
                shuffleArray($arr);
                var i = 0;
                var count = 0;
                intervalId = setInterval(function() {
                    $arr[i++].animate({
                        opacity: 1
                    }, duration, "", function() {
                        if (++count == total) {
                            slider.setComplete($img);
                        }
                    });
                    if (i == total) {
                        clearInterval(intervalId);
                    }
                }, delay);
            };

            init();
        }

        //class Blocks
        function Blocks(slider, areaWidth, areaHeight, blockSize, bgColor, duration, delay) {
            var $blockArr;
            var $blocks;
            var $arr;
            var numRows;
            var numCols;
            var total;
            var intervalId;

            //init blocks
            var init = function() {
                numRows = Math.ceil(areaHeight / blockSize);
                numCols = Math.ceil(areaWidth / blockSize);
                total = numRows * numCols;
                var divs = "";
                for (var i = 0; i < numRows; i++) {
                    for (var j = 0; j < numCols; j++) {
                        divs += "<div class='block' id='" + i + "-" + j + "'></div>";
                    }
                }
                slider.addToScreen(divs);
                $blocks = $("div.block", slider.$el);
                $blocks.data({
                    tlId: "0-0",
                    trId: "0-" + (numCols - 1),
                    blId: (numRows - 1) + "-0",
                    brId: (numRows - 1) + "-" + (numCols - 1)
                    });

                var k = 0;
                $arr = new Array(total);
                $blockArr = new Array(numRows);
                for (var i = 0; i < numRows; i++) {
                    $blockArr[i] = new Array(numCols);
                    for (var j = 0; j < numCols; j++) {
                        $blockArr[i][j] = $arr[k++] = $blocks.filter("#" + (i + "-" + j)).data("top", i * blockSize);
                    }
                }
            };

            //clear blocks
            this.clear = function() {
                clearInterval(intervalId);
                $blocks.stop(true).css({
                    "z-index": 2,
                    opacity: 0
                });
            };

            //set blocks 
            var setBlocks = function($img, opacity, size, tPos) {
                var tOffset = 0;
                var lOffset = 0;
                if (slider.centerImg()) {
                    tOffset = (areaHeight - $img.height()) / 2;
                    lOffset = (areaWidth - $img.width()) / 2;
                }
                var imgSrc = $img.attr("src");
                for (var i = 0; i < numRows; i++) {
                    for (var j = 0; j < numCols; j++) {
                        var tVal = (( - i * blockSize) + tOffset);
                        var lVal = (( - j * blockSize) + lOffset);
                        $blockArr[i][j].css({
                            background: bgColor + " url('" + imgSrc + "') no-repeat",
                            backgroundPosition: lVal + "px " + tVal + "px",
                            opacity: opacity,
                            top: (i * blockSize) + tPos,
                            left: (j * blockSize),
                            width: size,
                            height: size,
                            "z-index": 3
                        });
                    }
                }
            };

            //staircase effect
            var staircase = function($img, staircaseOut) {
                var i = 0,
                j = 0;
                var rowCount = numRows - 1;
                var colCount = numCols - 1;
                var dir = 0;
                var limit = colCount;
                var $array = new Array();
                while (rowCount >= 0 && colCount >= 0) {
                    var count = 0;
                    while (true) {
                        $array[$array.length] = $blockArr[i][j];
                        if ((++count) > limit) {
                            break;
                        }
                        switch (dir) {
                        case 0:
                            j++;
                            break;
                        case 1:
                            i++;
                            break;
                        case 2:
                            j--;
                            break;
                        case 3:
                            i--;
                            break;
                        }
                    }
                    switch (dir) {
                    case 0:
                        dir = 1;
                        limit = (--rowCount);
                        i++;
                        break;
                    case 1:
                        dir = 2;
                        limit = (--colCount);
                        j--;
                        break;
                    case 2:
                        dir = 3;
                        limit = (--rowCount);
                        i--;
                        break;
                    case 3:
                        dir = 0;
                        limit = (--colCount);
                        j++;
                        break;
                    }
                }
                if ($array.length > 0) {
                    if (staircaseOut) {
                        $array.reverse();
                    }
                    var end = $array.length - 1;
                    var lastId = $array[end].attr("id");
                    var k = 0;
                    intervalId = setInterval(function() {
                        $array[k].animate({
                            opacity: 1
                        }, duration, "", function() {
                            if ($(this).attr("id") == lastId) {
                                slider.setComplete($img);
                            }
                        });
                        if (k == end) {
                            clearInterval(intervalId);
                        }
                        k++;
                    }, delay);
                }
            };

            init();
        }

        //class Slide
        function Slide($obj, opts) {
            //set options
            var screenWidth = getPosNumber(opts.width, 825);
            var screenHeight = getPosNumber(opts.height, 300);
            var margin = getNonNegNumber(opts.button_margin, 4);
            var globalEffect = opts.transition.toLowerCase();
            var duration = getPosNumber(opts.transition_speed, DURATION);
            var globalDelay = getPosNumber(opts.delay, DEFAULT_DELAY);
            var slide = opts.auto_start;
            var scPos = opts.scontrol_position.toLowerCase();
            var scAlign = opts.scontrol_align.toUpperCase();
            var buttonWidth = getPosNumber(opts.button_width, 24);
            var buttonHeight = getPosNumber(opts.button_height, 24);
            var displayThumbs = opts.display_thumbs;
            var displayDBtns = opts.display_dbuttons;
            var displayPlayBtn = opts.display_playbutton;
            var scMouseover = opts.scontrol_mouseover;
            var textMousover = opts.text_mouseover;
            var pauseMouseover = opts.mouseover_pause;

            var textEffect = opts.text_effect.toLowerCase();
            var textSync = opts.text_sync;
            var playOnce = opts.play_once;
            var autoCenter = opts.auto_center;

            var numItems;
            var currIndex;
            var prevIndex;
            var delay;
            var vStripes;
            var hStripes;
            var blocks;
            var timerId = null;

            var $slider = $(".exdress-slider", $obj);
            var $screen = $slider.find("div.screen");
            var $mainLink;
            var $textBox;
            var $preloader;
            var $sControl = $slider.find("div.slider-control");
            var $thumbPanel = $sControl.find("div.thumbnails");
            var $thumbs = $thumbPanel.find(">ul:first>li");
            var $buttonPanel = $sControl.find("div.buttons");
            var $playBtn = $buttonPanel.find("div.play-btn");
            var $prevBtn = $buttonPanel.find("div.prev-btn");
            var $nextBtn = $buttonPanel.find("div.next-btn");
            var $timer;

            var $items;
            var $captionContent;
            this.$el = $obj;

            //init slider
            this.init = function() {
                currIndex = 0;
                prevIndex = -1;
                numItems = $thumbs.size();
                $items = new Array(numItems);

                //init components
                initScreen();
                initItems();
                initButtons();
                initSControl();
                initTimerBar();

                $slider.css({
                    width: screenWidth,
                    height: screenHeight
                });

                if (textMousover) {
                    $slider.hover(displayText, hideText);
                } else {
                    $slider.bind(UPDATE_TEXT, updateText);
                }

                //init transition components
                var bgColor = $screen.css("background-color");
                vStripes = new VerticalStripes(this, screenWidth, screenHeight, getPosNumber(opts.vert_size, 50), bgColor, duration, getPosNumber(opts.vstripe_delay, 75));
                hStripes = new HorizontalStripes(this, screenWidth, screenHeight, getPosNumber(opts.horz_size, 50), bgColor, duration, getPosNumber(opts.hstripe_delay, 75));
                blocks = new Blocks(this, screenWidth, screenHeight, getPosNumber(opts.block_size, 75), bgColor, duration, getPosNumber(opts.block_delay, 25));

                //init image loading
                loadImg(0);

                //display initial image
                loadContent(currIndex);
            };

            //set complete
            this.setComplete = function($img) {
                showContent($img);
            };

            //add to screen
            this.addToScreen = function(content) {
                $mainLink.append(content);
            };

            //get center image
            this.centerImg = function() {
                return autoCenter;
            };

            //init screen
            var initScreen = function() {
                var content = "<a href='#'></a>\
								<div class='caption'></div>\
								<div class='preloader'></div>\
								<div id='timer'></div>";
                $screen.empty().append(content);
                $mainLink = $screen.find(">a:first");
                $textBox = $screen.find("div.caption");
                $preloader = $screen.find("div.preloader");
                $screen.css({
                    width: screenWidth,
                    height: screenHeight
                });

                $textBox.append("<div class='caption-bg'></div><div class='caption-content'></div>");
                $captionContent = $textBox.find("div.caption-content");
            };

            //init control panel
            var initSControl = function() {
                if (displayThumbs || displayDBtns || displayPlayBtn) {
                    $thumbPanel.css("height", $thumbs.outerHeight());
                    var maxWidth = screenWidth - ($buttonPanel.width() + margin);
                    if ($thumbPanel.width() > maxWidth) {
                        $thumbPanel.width(maxWidth);
                    }
                    if (scPos == INSIDE) {
                        $sControl.css({
                            "margin-top": margin,
                            "margin-right": 0,
                            "margin-bottom": margin,
                            "margin-left": margin
                        });
                        var scWidth = $sControl.outerWidth(true);
                        var scHeight = $sControl.outerHeight(true);
                        switch (scAlign) {

                        case BOTTOM_LEFT:
                            setSControl((screenHeight - scHeight), 0, screenHeight, "left");
                            break;
                        case BOTTOM_CENTER:
                            setSControl((screenHeight - scHeight), Math.round((screenWidth - scWidth) / 2), screenHeight, "right");
                            break;
                        default:
                            setSControl((screenHeight - scHeight), (screenWidth - scWidth), screenHeight, "right");
                        	break;
                        }

                        if (scMouseover) {
                            $slider.hover(displaySControl, hideSControl);
                        }
                    } else {
                        if ($slider.outerWidth() - $slider.width() > 0) {
                            $sControl.css({
                                "border-left": "none",
                                "border-right": "none"
                            });
                        }
                        $sControl.css({
                            "padding-top": margin,
                            "padding-bottom": margin
                        }).addClass("sc-bg");
                        var scWidth = $sControl.outerWidth();

                    }
                    $sControl.css("visibility", "visible");
                }
            };

            //set control panel attributes
            var setSControl = function(yPos, xPos, offset, align) {
                $sControl.data({
                    offset: offset,
                    pos: yPos
                }).css({
                    top: (scMouseover ? offset: yPos),
                    left: xPos
                });
                $thumbPanel.css("float", align);
                $buttonPanel.css("float", align);
            };

            //init buttons
            var initButtons = function() {
                var props = {
                    "margin-right": margin,
                    width: buttonWidth,
                    height: buttonHeight
                };
                //config directional buttons
                if (displayDBtns) {
                    $prevBtn.css(props).click(prevImg).mouseover(buttonOver).mouseout(buttonOut).mousedown(preventDefault);
                    $nextBtn.css(props).click(nextImg).mouseover(buttonOver).mouseout(buttonOut).mousedown(preventDefault);
                } else {
                    $prevBtn.hide();
                    $nextBtn.hide();
                }

                //config play button
                if (displayPlayBtn) {
                    if (slide) {
                        $playBtn.addClass("pause");
                    }
                    $playBtn.css(props).click(togglePlay).mouseover(buttonOver).mouseout(buttonOut).mousedown(preventDefault);
                } else {
                    $playBtn.hide();
                }

                if (pauseMouseover) {
                    $slider.hover(pause, play);
                }
            };

            //init timer bar
            var initTimerBar = function() {
                $timer = $screen.find("#timer").data("pct", 1);
                if (opts.display_timer) {
                    var align = opts.timer_align.toLowerCase();
                    $timer.css("visibility", "visible");
                    $timer.css(align == "bottom" ? "bottom": "top", 0);
                } else {
                    $timer.hide();
                }
            };

            //init items
            var initItems = function() {
                var padding = $captionContent.outerHeight() - $captionContent.height();
                $thumbs.each(function(n) {
                    var $imgLink = $(this).find(">a:first");
                    $(this).data({
                        imgurl: $imgLink.attr("href"),
                        caption: $imgLink.attr("title"),
                        tturl: $imgLink.find(">img:first").attr("src"),
                        effect: EFFECTS[$(this).attr("effect")] != undefined ? EFFECTS[$(this).attr("effect")] : EFFECTS[globalEffect],
                        delay: getPosNumber($(this).attr("delay"), globalDelay)
                        });
                    initTextData($(this), padding);
                    $items[n] = $(this);

                    if (opts.display_numbers) {
                        $(this).append(n + 1);
                    }
                });
                $captionContent.css({
                    width: "auto",
                    height: "auto"
                }).html("");
                $textBox.css("visibility", "visible");

                if (opts.shuffle) {
                    shuffleItems();
                }

                if (displayThumbs) {
                    $thumbPanel.click(selectItem);
                    $thumbs.css({
                        width: buttonWidth,
                        height: buttonHeight,
                        "line-height": buttonHeight + "px",
                        "margin-right": margin
                    }).mouseover(itemOver).mouseout(itemOut).mousedown(preventDefault);

                } else {
                    $thumbs.hide();
                }
            };

            //init text data
            var initTextData = function($item, padding) {
                var $p = $item.find(">div:hidden");
                var textWidth = getPosNumber(parseInt($p.css("width")) - padding, 300);
                var textHeight = getPosNumber(parseInt($p.css("height")) - padding, 0);
                $captionContent.width(textWidth).html($p.html());
                if (textHeight < $captionContent.height()) {
                    textHeight = $captionContent.height();
                }
                $item.data("textbox", {
                    x: $p.css("left"),
                    y: $p.css("top"),
                    w: textWidth + padding,
                    h: textHeight + padding,
                    color: $p.css("color"),
                    bgcolor: $p.css("background-color")
                    });
            };

            //display control panel
            var displaySControl = function() {
                $sControl.stop(true).animate({
                    top: $sControl.data("pos"),
                    opacity: 1
                }, ANIMATE_SPEED);
            };

            //hide control panel
            var hideSControl = function() {
                $sControl.stop(true).animate({
                    top: $sControl.data("offset"),
                    opacity: 0
                }, ANIMATE_SPEED);
            };

            //select list item
            var selectItem = function(e) {
                if (e.target.nodeName == "LI") {
                    var i = $(e.target).index();
                    if (i >= 0 && i != currIndex) {
                        resetTimer();
                        prevIndex = currIndex;
                        currIndex = i;
                        loadContent(currIndex);

                    }
                }
                return false;
            };

            //on item mouseover
            var itemOver = function() {
                $(this).addClass("thumb-over");
            };

            //on item mouseout
            var itemOut = function() {
                $(this).removeClass("thumb-over");
            };

            //go to previous image
            var prevImg = function() {
                resetTimer();
                prevIndex = currIndex;
                currIndex = (currIndex > 0) ? (currIndex - 1) : (numItems - 1);
                loadContent(currIndex);
                return false;
            };

            //go to next image
            var nextImg = function() {
                resetTimer();
                prevIndex = currIndex;
                currIndex = (currIndex < numItems - 1) ? (currIndex + 1) : 0;
                loadContent(currIndex);
                return false;
            };

            //play/pause
            var togglePlay = function() {
                slide = !slide;
                $(this).toggleClass("pause", slide);
                slide ? startTimer() : pauseTimer();
                return false;
            };

            //play
            var play = function() {
                slide = true;
                $playBtn.toggleClass("pause", slide);
                startTimer();
            };

            //pause
            var pause = function() {
                slide = false;
                $playBtn.toggleClass("pause", slide);
                pauseTimer();
            };

            //pause on last item
            var pauseLast = function(i) {
                if (i == numItems - 1) {
                    slide = false;
                    $playBtn.toggleClass("pause", slide);
                }
            };

            //on button over
            var buttonOver = function() {
                $(this).addClass("button-over");
            };

            //on button out
            var buttonOut = function() {
                $(this).removeClass("button-over");
            };

            //update text box
            var updateText = function(e) {
                if (!$textBox.data("visible")) {
                    $textBox.data("visible", true);
                    var text = $items[currIndex].find(">div:first").html();
                    if (text && text.length > 0) {
                        var data = $items[currIndex].data("textbox");
                        $captionContent.css("color", data.color);
                        $textBox.find(".caption-bg").css("background-color", data.bgcolor);
                        switch (TEXT_EFFECTS[textEffect]) {
                        case TEXT_EFFECTS["fade"]:
                            fadeInText(text, data);
                            break;
                        case TEXT_EFFECTS["down"]:
                            expandText(text, {
                                display: "block",
                                top: data.y,
                                left: data.x,
                                width: data.w,
                                height: 0
                            }, {
                                height: data.h
                            });
                            break;
                        case TEXT_EFFECTS["right"]:
                            expandText(text, {
                                display: "block",
                                top: data.y,
                                left: data.x,
                                width: 0,
                                height: data.h
                            }, {
                                width: data.w
                            });
                            break;
                        default:
                            showText(text, data);
                        	break;
                        }
                    }
                }
            };

            //reset text box
            var resetText = function() {
                $textBox.data("visible", false).stop(true, true);
                switch (TEXT_EFFECTS[textEffect]) {
                case TEXT_EFFECTS["fade"]:
                    if (jQuery.browser.msie) {
                        $captionContent.css("opacity", 0);
                    }
                    $textBox.fadeOut(ANIMATE_SPEED, function() {
                        $(this).css("display", "none");
                    });
                    break;
                case TEXT_EFFECTS["down"]:
                    $captionContent.html("");
                    $textBox.animate({
                        height:
                        0
                    }, ANIMATE_SPEED);
                    break;
                case TEXT_EFFECTS["right"]:
                    $captionContent.html("");
                    $textBox.animate({
                        width:
                        0
                    }, ANIMATE_SPEED);
                    break;
                default:
                    $textBox.css("display", "none");
                	break;
                }
            };

            //expand text effect
            var expandText = function(text, props1, props2) {
                $captionContent.html("");
                $textBox.stop(true).css(props1).animate(props2, ANIMATE_SPEED, function() {
                    $captionContent.html(text);
                });
            };

            //fade in text effect
            var fadeInText = function(text, data) {
                $captionContent.css("opacity", 1).html(text);
                $textBox.css({
                    top: data.y,
                    left: data.x,
                    width: data.w,
                    height: data.h
                }).stop(true, true).fadeIn(ANIMATE_SPEED, function() {
                    if (jQuery.browser.msie) {
                        $captionContent[0].style.removeAttribute('filter');
                    }
                });
            };

            //show text effect
            var showText = function(text, data) {
                $textBox.stop(true).css({
                    display: "block",
                    top: data.y,
                    left: data.x,
                    width: data.w,
                    height: data.h
                });
                $captionContent.html(text);
            };

            //display text panel on mouseover
            var displayText = function() {
                $slider.unbind(UPDATE_TEXT).bind(UPDATE_TEXT, updateText).trigger(UPDATE_TEXT);
            };

            //hide text panel on mouseovers
            var hideText = function() {
                $slider.unbind(UPDATE_TEXT);
                resetText();
            };

            //load current content
            var loadContent = function(i) {
                if (playOnce) {
                    pauseLast(i);
                }

                //select thumb
                $thumbs.filter(".curr-thumb").removeClass("curr-thumb");
                $($thumbs.get(i)).addClass("curr-thumb");

                //set delay
                delay = $items[i].data("delay");

                //reset text
                resetText();
                if (!textSync) {
                    $slider.trigger(UPDATE_TEXT);
                }

                //set link
                var $currLink = $items[i].find(">a:nth-child(2)");
                var href = $currLink.attr("href");
                if (href) {
                    $mainLink.unbind("click").css("cursor", "pointer").attr({
                        href: href,
                        target: $currLink.attr("target")
                        });
                } else {
                    $mainLink.click(preventDefault).css("cursor", "default");
                }

                //load image
                if ($items[i].data("img")) {
                    $preloader.hide();
                    displayContent($items[i].data("img"));
                } else {
                    //load new image
                    var $img = $("<img class='main-img'/>");
                    $img.attr("src", $items[i].data("imgurl"));
                    if ($img[0].complete || $img[0].readyState == "complete") {
                        $preloader.hide();
                        storeImg($items[i], $img);
                        displayContent($img);
                    } else {
                        $preloader.show();
                        $img.load(function() {
                            $preloader.hide();
                            storeImg($items[i], $(this));
                            displayContent($(this));
                        }).error(function() {
                            alert("Error loading image");
                        });
                    }
                }
            };

            //display content
            var displayContent = function($img) {
                //clear
                vStripes.clear();
                hStripes.clear();
                blocks.clear();
                setPrevious();

                //get effect number
                var effect = $items[currIndex].data("effect");
                if (effect == EFFECTS["none"]) {
                    showContent($img);
                    return;
                }

                if (effect == EFFECTS["random"]) {
                    effect = Math.floor(Math.random() * (EFFECTS.length - 2));
                }

                if (effect == EFFECTS["fade"]) {
                    fadeInContent($img);
                } else if (effect < EFFECTS["vertical.tile"]) {
                    blocks.displayContent($img, effect);
                } else if (effect < EFFECTS["horizontal.tile"]) {
                    vStripes.displayContent($img, effect);
                } else {
                    hStripes.displayContent($img, effect);
                }
            };

            //set previous
            var setPrevious = function() {
                if (prevIndex >= 0) {
                    var currSrc = $("img#curr-img").attr("src");
                    var prevSrc = $items[prevIndex].data("imgurl");
                    if (currSrc != prevSrc) {
                        $("img.main-img", $mainLink).removeAttr("id").hide();
                        var $img = $("img.main-img", $mainLink).filter(function() {
                            return $(this).attr("src") == prevSrc;
                        });
                        $($img.get(0)).show();
                    }
                }
            };

            //display content (no effect)
            var showContent = function($img) {
                if (textSync) {
                    $slider.trigger(UPDATE_TEXT);
                }
                $("img.main-img", $mainLink).removeAttr("id").hide();
                $img.attr("id", "curr-img").show();
                startTimer();
            };

            //display content (fade effect)
            var fadeInContent = function($img) {
                $("img#curr-img", $mainLink).stop(true, true);
                $("img.main-img", $mainLink).removeAttr("id").css("z-index", 0);
                $img.attr("id", "curr-img").css("z-index", 1).stop(true, true).fadeIn(duration, function() {
                    $("img.main-img:not('#curr-img')", $mainLink).hide();
                    if (textSync) {
                        $slider.trigger(UPDATE_TEXT);
                    }
                    startTimer();
                });
            };

            //load image
            var loadImg = function(loadIndex) {
                var $item = $items[loadIndex];
                var $img = $("<img class='main-img'/>");
                $img.attr("src", $item.data("imgurl"));
                $img.load(function() {
                    if (!$item.data("img")) {
                        storeImg($item, $(this));
                    }
                    loadIndex++;
                    if (loadIndex < numItems) {
                        loadImg(loadIndex);
                    }
                }).error(function() {
                    //error loading image, continue next
                    loadIndex++;
                    if (loadIndex < numItems) {
                        loadImg(loadIndex);
                    }
                });
            };

            //process & store image
            var storeImg = function($item, $img) {
                $mainLink.append($img);
                if (autoCenter) {
                    var tDiff = (screenHeight - $img.height()) / 2;
                    var lDiff = (screenWidth - $img.width()) / 2;
                    var top = 0,
                    left = 0,
                    vPad = 0,
                    hPad = 0;
                    if (tDiff > 0) {
                        vPad = tDiff;
                    } else if (tDiff < 0) {
                        top = tDiff;
                    }
                    if (lDiff > 0) {
                        hPad = lDiff;
                    } else if (lDiff < 0) {
                        left = lDiff;
                    }
                    $img.css({
                        top: top,
                        left: left,
                        "padding-top": vPad,
                        "padding-bottom": vPad,
                        "padding-left": hPad,
                        "padding-right": hPad
                    });
                }
                $item.data("img", $img);
            };

            //start timer
            var startTimer = function() {
                if (slide && timerId === null) {
                    var duration = Math.round($timer.data("pct") * delay);
                    $timer.animate({
                        width: (screenWidth + 1)
                        }, duration);
                    timerId = setTimeout(nextImg, duration);
                }
            };

            //reset timer
            var resetTimer = function() {
                clearTimeout(timerId);
                timerId = null;
                $timer.stop(true).width(0).data("pct", 1);
            };

            //pause timer
            var pauseTimer = function() {
                clearTimeout(timerId);
                timerId = null;
                var pct = 1 - ($timer.width() / (screenWidth + 1));
                $timer.stop(true).data("pct", pct);
            };

            //shuffle items
            var shuffleItems = function() {
                for (var i = 0; i < $items.length; i++) {
                    var ri = Math.floor(Math.random() * $items.length);
                    var temp = $items[i];
                    $items[i] = $items[ri];
                    $items[ri] = temp;
                }
            };

            //prevent default behavior
            var preventDefault = function() {
                return false;
            };
        }

        //get positive number
        var getPosNumber = function(val, defaultVal) {
            if (!isNaN(val) && val > 0) {
                return val;
            }
            return defaultVal;
        };

        //get nonnegative number
        var getNonNegNumber = function(val, defaultVal) {
            if (!isNaN(val) && val >= 0) {
                return val;
            }
            return defaultVal;
        };

        //shuffle array
        var shuffleArray = function(arr) {
            var total = arr.length;
            for (var i = 0; i < total; i++) {
                var ri = Math.floor(Math.random() * total);
                var temp = arr[i];
                arr[i] = arr[ri];
                arr[ri] = temp;
            }
        };

        var defaults = {
            width: 960,
            height: 430,
            button_width: 24,
            button_height: 24,
            button_margin: 5,
            auto_start: true,
            delay: DEFAULT_DELAY,
            transition: "fade",
            transition_speed: DURATION,
            scontrol_position: INSIDE,
            scontrol_align: BOTTOM_RIGHT,
            timer_align: "top",
            display_thumbs: true,
            display_dbuttons: true,
            display_playbutton: true,
            display_numbers: false,
            display_timer: false,
            mouseover_pause: false,
            scontrol_mouseover: false,
            text_mouseover: false,
            text_effect: "fade",
            text_sync: true,
            shuffle: false,
            play_once: false,
            auto_center: false,
            block_size: 75,
            vert_size: 50,
            horz_size: 50,
            block_delay: 25,
            vstripe_delay: 75,
            hstripe_delay: 75,
        };

        var opts = $.extend({}, defaults, params);
        return this.each(function() {
            var slider = new Slide($(this), opts);
            slider.init();
        });
    };
})(jQuery);
