var slideNavigation = Class.create();
slideNavigation.prototype = {
    initialize: function(id, option) {
        this.id = id;
        this.option = Object.extend({
            event: "click",
            dur: 0.7,
            interval: 3,
            type: 0,
            gap: 9,
            isPreLoad: false,
            isAuto: false,
            navNow: 'navNow',
            handle: 'handle',
            slide: 'slide',
            goLeftImg: ['/images/arrow_right_orange.gif', '/images/arrow_right_green.gif', '/images/arrow_right_gray.gif'],
            goRightImg: ['/images/arrow_left_orange.gif', '/images/arrow_left_green.gif', '/images/arrow_left_gray.gif'],
            loadingImg: '/images/loading.gif'
        }, option ||
        {});
        this.event = this.option.event;
        this.interval = this.option.interval;
        this.dur = this.option.dur;
        this.gap = this.option.gap;
        this.navNow = this.option.navNow;
        this.goLeftImg = this.option.goLeftImg;
        this.goRightImg = this.option.goRightImg;
        this.intervarID;
        this.isShowNum = 0;
        this.obj = $(id);
        if (this.obj) {
            this.main = this.obj.down();
            this.bigImg = this.main.down().down().down();
            //this.bigImg = this.main.down();
            this.imgDims = this.main.getDimensions();
            this.goRight = this.main.next().down();
            this.goLeft = this.main.next(2).down();
            this.slider = this.main.next(3);
            this.handle = this.slider.down();
            this.handleValue = 0;
            this.slider_ctrl;
            this.nav = this.main.next(1).down();
            this.navMaskWidth = this.nav.up().getWidth();
            this.navImgWidth = this.nav.down().getWidth();
            this.imgAllNum = this.nav.childElements().length;
            this.navWidth = this.imgAllNum * (this.navImgWidth + this.gap) - this.gap;
            this.imgArr = [];
            this.goLeftOn = true;
            this.goRightOn = true;
            this.objOver = this.stop.bind(this);
            this.objOut = this.start.bind(this);
            this.init();
        }
    },
    
    init: function() {
        this.render();
        if (this.option.isAuto) 
            this.auto();
        this.nav.observe('mouseover', this.imgOver);
        document.observe('keydown', this.keyboardAction.bind(this));
    },
    
    render: function() {
    
        this.imgArr = this.nav.childElements().collect(function(o) {
            return o.down().href;
        });
        
        this.main.insert('<div id="loading"><img id="loadingImg" src="' + this.option.loadingImg + '" /></div>');
        //this.loading = this.main.insert('<div id="loading"><img src="' + this.option.loadingImg + '" /></div>').down(1).next().hide();
        
        
        this.nav.childElements().each(function(o, i) {
            o.setStyle({
                left: i * (this.navImgWidth + this.gap) + 'px'
            });
            o.observe(this.event, this.navEvent.bindAsEventListener(this, i));
        }
.bind(this));
        
        
        this.nav.insert('<li id="' + this.navNow + '"></li>');
        this.navNowMv(0);
        
        this.loading = $('loadingImg').hide();
        this.changeImage(0);
        
        
        if (this.navWidth < this.navMaskWidth) {
            this.slider.hide();
            this.goLeft.hide();
            this.goRight.hide();
        }
        else {
            this.goRightDisabled();
            this.slider_ctrl = new Control.Slider(this.handle, this.slider, {
                onSlide: function(v) {
                    this.slideCallback(v, false);
                }
.bind(this)                ,
                onChange: function(v) {
                    this.slideCallback(v, true);
                }
.bind(this)
            });
            this.goLeft.observe('click', this.goLeftClick.bind(this));
            this.goRight.observe('click', this.goRightClick.bind(this));
            this.goLeft.observe('mouseover', this.goLeftOver.bind(this));
            this.goRight.observe('mouseover', this.goRightOver.bind(this));
            this.goLeft.observe('mousedown', this.goLeftOver.bind(this));
            this.goRight.observe('mousedown', this.goRightOver.bind(this));
            this.goLeft.observe('mouseout', this.goLeftOut.bind(this));
            this.goRight.observe('mouseout', this.goRightOut.bind(this));
        };
        
        
        if (this.option.isPreLoad) {
            this.imgArr.each(function(o, i) {
                var preloadImg = new Image();
                preloadImg.src = this.imgArr[i];
            }
.bind(this));
        }
    },
    
    changeImage: function(imgNum) {
        this.isShowNum = imgNum;
        this.bigImg.hide();
        if (Prototype.Browser.IE) {
            this.bigImg.src = this.option.loadingImg;
        }
        this.loading.show();
        var imgPreloader = new Image();
        imgPreloader.onload = function() {
            this.bigImg.src = this.imgArr[this.isShowNum];
            this.showImage();
        }
.bind(this);
        imgPreloader.src = this.imgArr[this.isShowNum];
    },
    
    showImage: function() {
        this.loading.hide();
        new Effect.Appear(this.bigImg, {
            duration: this.dur
        });
    },
    
    
    changeNav: function(isNext) {
        isNext ? this.isShowNum++ : this.isShowNum--;
        if (this.isShowNum == this.imgAllNum) {
            this.isShowNum = 0;
        }
        if (this.isShowNum < 0) {
            this.isShowNum = this.imgAllNum - 1;
        }
        var posNew = parseInt(this.nav.childElements()[this.isShowNum].getStyle('left'));
        var posNav = parseInt(this.nav.getStyle('left'));
        var widthAll = this.navWidth - this.navMaskWidth;
        
        if (posNew <= 0) {
            this.navMv(0);
            if (this.slider_ctrl) {
                this.slider_ctrl.setValue(0);
            }
        }
        else if (posNew >= widthAll) {
            this.navMv(widthAll);
            if (this.slider_ctrl) {
                this.slider_ctrl.setValue(1);
            }
        }
        else {
            this.navMv(posNew);
            if (this.slider_ctrl) {
                this.slider_ctrl.setValue(posNew / widthAll);
            }
        }
        this.navNowMv(posNew);
        this.changeImage(this.isShowNum);
    },
    
    
    navEvent: function(e, i) {
        e.stop();
        var posNew = parseInt(e.element().up('li').getStyle('left'));
        this.navNowMv(posNew);
        this.changeImage(i);
    },
    
    
    navNowMv: function(pos) {
        new Effect.Morph(this.navNow, {
            style: "left:" + pos + "px",
            duration: this.dur
        });
    },
    
    
    navMv: function(pos) {
        new Effect.Morph(this.nav, {
            style: "left:-" + pos + "px",
            duration: this.dur
        });
    },
    
    goLeftClick: function(e) {
        if (this.handleValue != 1) {
            var posNow = parseInt(this.nav.getStyle("left"));
            var posNew;
            var temp1 = posNow - this.navMaskWidth;
            var temp2 = -(this.navWidth - this.navMaskWidth);
            posNew = temp1 < temp2 ? -temp2 : -temp1;
            if (this.slider_ctrl) {
                this.slider_ctrl.setValue(posNew / -temp2);
            }
            this.navMv(posNew);
        }
    },
    
    goRightClick: function(e) {
        if (this.handleValue != 0) {
            var posNow = parseInt(this.nav.getStyle("left"));
            var posNew;
            var temp1 = posNow + this.navMaskWidth;
            var temp2 = -(this.navWidth - this.navMaskWidth);
            posNew = temp1 > 0 ? 0 : -temp1;
            if (this.slider_ctrl) {
                this.slider_ctrl.setValue(posNew / -temp2);
            }
            this.navMv(posNew);
        }
    },
    
    goLeftOver: function(e) {
        if (this.handleValue != 1) {
            e.element().setStyle({
                background: "url(" + this.goLeftImg[1] + ")"
            });
        }
    },
    
    goRightOver: function(e) {
        if (this.handleValue != 0) {
            e.element().setStyle({
                background: "url(" + this.goRightImg[1] + ")"
            });
        }
    },
    
    goLeftOut: function(e) {
        if (this.handleValue != 1) {
            e.element().setStyle({
                background: "url(" + this.goLeftImg[0] + ")"
            });
        }
    },
    
    goRightOut: function(e) {
        if (this.handleValue != 0) {
            e.element().setStyle({
                background: "url(" + this.goRightImg[0] + ")"
            });
        }
    },
    
    goLeftEnabled: function() {
        if (!this.goLeftOn) {
            this.goLeft.setStyle({
                background: "url(" + this.goLeftImg[0] + ")",
                cursor: "pointer"
            });
            this.goLeftOn = true;
        }
    },
    
    goRightEnabled: function() {
        if (!this.goRightOn) {
            this.goRight.setStyle({
                background: "url(" + this.goRightImg[0] + ")",
                cursor: "pointer"
            });
            this.goRightOn = true;
        }
    },
    
    goLeftDisabled: function() {
        if (this.goLeftOn) {
            this.goLeft.setStyle({
                background: "url(" + this.goLeftImg[2] + ")",
                cursor: "auto"
            });
            this.goLeftOn = false;
        }
    },
    
    goRightDisabled: function() {
        if (this.goRightOn) {
            this.goRight.setStyle({
                background: "url(" + this.goRightImg[2] + ")",
                cursor: "auto"
            });
            this.goRightOn = false;
        }
    },
    
    
    slideCallback: function(v, isMV) {
        this.handleValue = v;
        if (isMV) {
            new Effect.Morph(this.nav, {
                style: "left:-" + Math.floor(v * (this.navWidth - this.navMaskWidth)) + "px",
                duration: this.dur
            });
        }
        else {
            this.nav.setStyle("left:-" + Math.floor(v * (this.navWidth - this.navMaskWidth)) + "px");
        }
        if (v == 1) {
            this.goLeftDisabled();
            this.goRightEnabled();
        }
        else if (v == 0) {
            this.goRightDisabled();
            this.goLeftEnabled();
        }
        else {
            this.goLeftEnabled();
            this.goRightEnabled();
        }
    },
    
    start: function() {
        if (!this.intervarID) {
            this.intervarID = new PeriodicalExecuter(this.changeNav.bind(this, true), this.interval);
        }
    },
    
    stop: function() {
        if (this.intervarID) {
            this.intervarID.stop();
            this.intervarID = 0;
        }
    },
    
    toggle: function() {
        this.intervarID ? this.stopAuto() : this.auto();
    },
    
    next: function() {
        this.changeNav(true);
    },
    
    prev: function() {
        this.changeNav(false);
    },
    
    setInterval: function(interval) {
        if (isNaN(interval) || interval < 1) {
            $("interval").value = "1";
            interval = 1;
        }
        this.interval = interval;
        this.stopAuto();
        this.auto();
    },
    
    auto: function() {
        this.start();
        this.obj.observe('mouseover', this.objOver);
        this.obj.observe('mouseout', this.objOut);
    },
    
    stopAuto: function() {
        this.stop();
        this.obj.stopObserving('mouseover', this.objOver);
        this.obj.stopObserving('mouseout', this.objOut);
    },
    
    keyboardAction: function(e) {
        var keycode = e.keyCode;
        var key = String.fromCharCode(e.keyCode).toLowerCase();
        
        if ((key == 'p') || (keycode == 37)) {
            this.changeNav(false);
        }
        else if ((key == 'n') || (keycode == 39)) {
            this.changeNav(true);
        }
    },
    
    imgOver: function(e) {
        var o = e.element();
        if (o.tagName == "IMG") {
            new Effect.Opacity(o, {
                from: 0,
                to: 1,
                duration: 0.3
            });
        }
    }
};

