(function($) {

    $.fn.slider = function(vars) {

        var element = this;
        var timeOutMs = (vars.timeOut != undefined) ? vars.timeOut : 4000;
        var timeOutChangeSlideMs = (vars.timeOutChangeSlide != undefined) ? vars.timeOutChangeSlide : 200;
        var current = 0;
        var timeOutFn = null;
        var faderStat = true;
        var mOverSlider = false;
        var mOverSpan = false;
        var mOverButton = false;
        var lock = false;
        var goNextSlide = false;
        var items = $("#" + element[0].id + "Content ." + element[0].id + "Image");
        var itemsSpan = $("#" + element[0].id + "Content ." + element[0].id + "Image span");
        // Insert controls in the DOM

        $('.control')
                .bind('click', function() {
            ($(this).attr('id') == 'rightControl') ? changeNextSlide() : changePrevSlide();

        });

        $('.control').mouseover(function() {
            mOverButton = true;
            //console.log("Slider[" + mOverSlider + "] Span["+mOverSpan+"] Control[" + mOverButton + "] isShowControl[" +isShowButton() +"]");
            manageControls();
        });

        $('.control').mouseout(function() {
            mOverButton = false;
            //console.log("Slider[" + mOverSlider + "] Span["+mOverSpan+"] Control[" + mOverButton + "] isShowControl[" +isShowButton() +"]");
            manageControls();
            if (!isShowButton()) {
                //console.log("Fade");
                fadeElement(true);
            }
        });

        var isShowButton = function() {
            if (mOverSlider || mOverSpan) {
                return true;
            } else {
                return mOverButton;
            }
        };
        /*
         $('#slider1')
         .prepend('<span class="control" id="leftControl">Clicking moves left</span>')
         .append('<span class="control" id="rightControl">Clicking moves right</span>');
         */
        var manageControls = function() {
            // Hide left arrow if position is first slide
            if (isShowButton()) {
                /** Code to uncomment to
                 *     + hide the right button on last slide
                 *     + hide the left button on last slide
                if (current == 0) {
                    $('#leftControl').hide();
                    //console.log("hide left");
                } else {
                    $('#leftControl').show();
                    //console.log("show left");
                }
                if (current == items.length - 1) {
                    $('#rightControl').hide();
                    //console.log("hide right");
                } else {
                    $('#rightControl').show();
                    //console.log("show right");
                }
                 */
                $('#leftControl').show();
                $('#rightControl').show();
            } else {
                //console.log("hide all");
                $('#leftControl').hide();
                $('#rightControl').hide();
            }
        };

        itemsSpan.each(function(i) {

            $(itemsSpan[i]).mouseover(function() {
                mOverSpan = true;
                //console.log("Slider[" + mOverSlider + "] Span["+mOverSpan+"] Control[" + mOverButton + "] isShowControl[" +isShowButton() +"]");
                manageControls();
            });

            $(itemsSpan[i]).mouseout(function() {
                mOverSpan = false;
                //console.log("Slider[" + mOverSlider + "] Span["+mOverSpan+"] Control[" + mOverButton + "] isShowControl[" +isShowButton() +"]");
                if (!isShowButton()) {
                    //console.log("Fade");
                    fadeElement(true);
                }

            });

        });
        items.each(function(i) {

            $(items[i]).mouseover(function() {
                mOverSlider = true;
                //console.log("Slider[" + mOverSlider + "] Span["+mOverSpan+"] Control[" + mOverButton + "] isShowControl[" +isShowButton() +"]");
                manageControls();
            });

            $(items[i]).mouseout(function() {
                mOverSlider = false;
                //console.log("Slider[" + mOverSlider + "] Span["+mOverSpan+"] Control[" + mOverButton + "] isShowControl[" +isShowButton() +"]");
                if (!isShowButton()) {
                    //console.log("Fade");
                    fadeElement(true);
                }

            });

        });

        var changeNextSlide = function() {
            changeSlide(current + 1);
        };
        var changePrevSlide = function() {
            changeSlide(current - 1);
        };
        var changeSlide = function(pos) {
            timeOutFn = null;
            if (! faderStat) {
                goNextSlide = true;
                makeSlider(timeOutChangeSlideMs, function() {
                    goNextSlide = true;
                    current = ((items.length + pos) % items.length);
                    makeSlider(timeOutChangeSlideMs, function() {
                    });
                });
            } else {
                goNextSlide = true;
                current = ((items.length + pos) % items.length);
                makeSlider(timeOutChangeSlideMs, function() {
                });
            }

        };

        var fadeElement = function(isMouseOut) {
            if (faderStat) {
                thisTimeOut = 10;
            } else if (isMouseOut) {
                thisTimeOut = timeOutMs / 2;
            } else {
                thisTimeOut = timeOutMs;
            }
            timeOutFn = setTimeout(function() {
                if (!lock) {
                    makeSlider((timeOutMs / 6), function() {
                    });
                } else {
                    //console.log("Race condiion detected");
                }
            }, thisTimeOut);
        };


        // timer should be (timeOut / 6)
        var showImage = function(timer, currNo, callback) {
            $(items[currNo]).fadeIn(timer, function() {
                showText(timer, currNo, function() {
                    callback();
                });
            });
        };

        // timer should be (timeOut / 6)
        var showText = function(timer, currNo, callback) {
            // manage css right
            if ($(itemsSpan[currNo]).css('bottom') == 0) {
                $(itemsSpan[currNo]).slideUp(timer, function() {
                    faderStat = false;
                    current = currNo;
                    if (!isShowButton()) {
                        fadeElement(false);
                    }
                    callback();
                });
                // manage css left
            } else {
                $(itemsSpan[currNo]).slideDown(timer, function() {
                    faderStat = false;
                    current = currNo;
                    if (!isShowButton()) {
                        fadeElement(false);
                    }
                    callback();
                });
            }
        };

        // timer should be (timeOut / 6)
        var hideText = function(timer, currNo, callback) {
            // manage css right
            if ($(itemsSpan[currNo]).css('bottom') == 0) {
                $(itemsSpan[currNo]).slideDown(timer, function() {
                    $(items[currNo]).fadeOut(timer, function() {
                        faderStat = true;
                        current = ((currNo + 1) % items.length);
                        if (!isShowButton()) {
                            fadeElement(false);
                        }
                        callback();
                    });
                });
                // manage css left
            } else {
                $(itemsSpan[currNo]).slideUp(timer, function() {
                    $(items[currNo]).fadeOut(timer, function() {
                        faderStat = true;
                        current = ((currNo + 1) % items.length);
                        if (!isShowButton()) {
                            fadeElement(false);
                        }
                        callback();

                    });
                });
            }

        };

        var makeSlider = function(timer, callback) {
            //var newMargin = $(element).width() * current;
            lock = true;
            if (faderStat == true) {
                if (!isShowButton() || goNextSlide) {
                    showImage(timer, current, function() {
                        goNextSlide = false;
                        manageControls();
                        callback();
                    });
                }
            } else {
                if (!isShowButton() || goNextSlide) {
                    hideText(timer, current, function() {
                        goNextSlide = false;
                        manageControls();
                        callback();
                    });
                }
            }
            lock = false;
        };
        makeSlider((timeOutMs / 6), function() {
        });


    };

})(jQuery);
