var view = window.view || {};
var sizeOfSlide = 960;

view.slideViewer = new ui.SlideViewer({
        mover: $('ui_mover_mover'), 
        clipper: $('ui_mover_clipper'),
        sizeOfSlide: sizeOfSlide
});

view.controls = new ui.MouseView({
    element: $('hpc_btns'),
    subject: $('hp_carousel')
});
view.controls.fadeTo.bind(view.controls).delay(2, 0);

view.Carousel = {

    _navigating: false, 
    
    activeView: null,
    
    elements: {
        btnDetail:      $('btn_detail'),
        btnList:        $('btn_list'),
        btnNext:        $('btn_next'),
        btnViewDetail:  $('btn_view_detail'),
        btnPrev:        $('btn_prev'),
        ctr:            $('hp_carousel'),
        clipper:        $('ui_mover_clipper'),
        boxCtr:         $('ui_mover_box_ctr'),
        lCurtain:       $('l_curtain'),
        rCurtain:       $('r_curtain')
    },
    
    initialize: function(content) {
        view.List.initialize(content);
        view.Detail.initialize(content);
        this.activateView(view.Detail);
        this._events();
        this._layoutStage();
    },
    
    _layoutStage: function() {
        var vpWidth = document.viewport.getWidth(),
            halfDiffVpAndSlide = ((vpWidth - sizeOfSlide)/2).round(),
            buttonWidth = this.elements.btnPrev.getWidth(),
            detailPos = ((vpWidth - this.elements.btnViewDetail.getWidth())/2).round(),
            buttonPos = halfDiffVpAndSlide - buttonWidth; 

        [   
            this.elements.lCurtain, 
            this.elements.rCurtain 
        ].invoke('setStyle', {
            width: halfDiffVpAndSlide + 'px'
        });
        this.elements.btnPrev.setStyle({left: buttonPos + 'px'});
        this.elements.btnNext.setStyle({right: buttonPos + 'px'});
        this.elements.boxCtr.setStyle({right: halfDiffVpAndSlide + 'px'});
        this.elements.btnViewDetail.setStyle({left: detailPos + 'px'});
        this.elements.clipper.setStyle({width: vpWidth + 'px'});
        
        //use margin left to center the slides
        if(vpWidth > sizeOfSlide) {
            view.slideViewer.getMover().setStyle({
                    left: halfDiffVpAndSlide - sizeOfSlide + 'px'
            });
        }
    },
    
    activateView: function(activeView, item) {
        if(this._navigating) return;
        if(this.activeView == activeView) return;
        this.elements.ctr.className = activeView.CLASSNAME;
        
        // deregister stale handlers
        [this.elements.btnNext, this.elements.btnPrev].invoke('stopObserving', 'click');
        
        // register new ones
        this.elements.btnNext.observe('click', activeView.next.bind(activeView));
        this.elements.btnPrev.observe('click', activeView.prev.bind(activeView));
        
        view.Detail.hideBox();
        
        if(this.activeView) {
            // crossfade if we already have a view selected 
            var element = view.slideViewer.getMover();
            var parent = view.slideViewer.getMover().up();
            var clone = element.cloneNode(true);
            clone.id = 'ui_mover_clone';
            parent.insert(clone);
            
            activeView.start(item);
            
            clone.setStylePeriodically({
                    property:   'opacity',
                    startValue: 0.99,
                    endValue:   0,
                    increment:  0.25,
                    onComplete: clone.remove.bind(clone)
            });

        } else {
            activeView.start(item);
        }
        this._layoutStage();
        this.activeView = activeView;
    },
    
    setNavigating: function(navigating) {
        this._navigating = navigating;
    },
    
    isNavigating: function() {
        return this._navigating;
    },
    
    enableNavigation: function() {
        [this.elements.btnNext, this.elements.btnPrev].invoke('show');
        [this.elements.lCurtain, this.elements.rCurtain].invoke('removeClassName', 'closed_curtain');
    },
    
    disableNavigation: function() {
        [this.elements.btnNext, this.elements.btnPrev].invoke('hide');
        [this.elements.lCurtain, this.elements.rCurtain].invoke('addClassName', 'closed_curtain');
    },
    
    observeKeyDown: function(activeView) {
        document.observe('keydown', 
            function(evt){
                if(evt.keyCode == Event.KEY_UP || evt.keyCode == Event.KEY_DOWN) {
                    Event.stop(evt);
                }
                (evt.keyCode == Event.KEY_RIGHT) && this.activeView.next();
                (evt.keyCode == Event.KEY_LEFT) && this.activeView.prev();
                (evt.keyCode == Event.KEY_UP) && view.Carousel.activateView(view.List, view.Detail.currentItem());
                (evt.keyCode == Event.KEY_DOWN) && view.Carousel.activateView(view.Detail);
            }.bind(this)
        );
    },
    
    _events: function() {
        this.elements.btnList.observe('click', function(){view.Carousel.activateView(view.List, view.Detail.currentItem())});
        this.elements.btnDetail.observe('click', function(){view.Carousel.activateView(view.Detail)});
        Event.observe(window, 'resize', 
            function(evt) {
                this._layoutStage();
            }.bind(this)
        );
        this.observeKeyDown();
    }
    
};

view.Detail = {

    CLASSNAME: 'detail_view',
    
    _tid: null,
    _pe: null,
    
    segments: {}, // struct.SegmentedList
    
    elements: {
        box: $('ui_mover_box'),
        boxCtr: $('ui_mover_box_ctr'),
        btnDetail: $('btn_view_detail'),
        client: $('work_client'),
        project: $('work_project'),
        disciplines: $('work_disciplines')
    },
    
    initialize: function(content) {
        this.segments = new struct.SegmentedList(3, content); // add the content list to the SegmentedList instance
    },
    
    start: function(atItem) {
        view.Carousel.enableNavigation();
        if(atItem) {
            // we want the segment that has the item in the middle
            this.segments.setCurrentSegmentByItem(atItem);
            this.segments.prev();
        }
        this.write();
    },
    
    next: function() {
        this._navigate(1);
    },
    
    prev: function() {
        this._navigate(-1);
    },
    
    write: function() {
        view.slideViewer.clear();
        this.segments.current().items.each(
            function(obj) {
                view.slideViewer.push(
                    this._newPage(obj)
                );                
            }.bind(this)
        );
        this.elements.btnDetail.href = this.currentItem().href;
        this.showBox(this.currentItem().box);
        this.updateText(this.currentItem());
    },
    
    _newPage: function(obj) {
        return new Element('A', {
                href: obj.href,
                target: '_new'
            })
            .insert(
                new Element('IMG', {
                    src: obj.image
                })
            );
    },
    
    updateText: function(item) {
        Object.keys(item.text).each(
            function(key){
                this.elements[key].update(item.text[key]);
            }.bind(this)
        );
    },
    
    showBox: function(src) {
        var box = this.elements.box, boxCtr = this.elements.boxCtr;
        box.onload = function() {
            boxCtr.show();
            this._tid = function(){
                this._pe = box.setStylePeriodically({
                        property:   'opacity',
                        startValue: 0,
                        endValue:   0.99,
                        increment:  0.1
                });
            }.bind(this).delay(.33);
        }.bind(this);
        
        box.src = src;
    },
    
    hideBox: function() {
        this._pe && this._pe.stop();
        this._tid && window.clearTimeout(this._tid);
        // this.elements.box.setStyle({top: ''});
        this.elements.box.setOpacity(0);
        this.elements.boxCtr.hide();
    },
    
    currentSegment: function() {
        return this.segments.current();
    },
    
    currentItem: function() {
        return this.segments.current().items[1]; // TODO: dynamic
    },
    
    _navigate: function(by) { // TODO: maybe support nav by mult items and make public
        if(view.Carousel.isNavigating()) return;
        view.Carousel.setNavigating(true);
        if(this._tid) {
            window.clearInterval(this._tid);
            this._tid = null;
        }
        var nextSeg = this.segments[(by > 0 ? 'next' : 'prev')]();
        var newImage = this._newPage(nextSeg.items[(by > 0 ? 'last' : 'first')]());
        var destItem = nextSeg.items[1]; // TODO: dynamic
        view.slideViewer[(by > 0 ? 'push' : 'unshift')](newImage);
        this.hideBox();
        view.slideViewer.navigate(by,
            function(){
                view.slideViewer[(by > 0 ? 'shift' : 'pop')]();
                this.showBox(destItem.box);
                this.updateText(destItem);
                this.elements.btnDetail.href = this.currentItem().href;
                view.Carousel.setNavigating(false);
            }.bind(this)
        );
    }
    
};

view.List = {

    CLASSNAME: 'list_view',
    
    segments: [], // Array
    
    pagesDisplayed: 3,
    
    thumbsPerPage: 8,
    
    initialize: function(content) {
        this.content = content;
        if(this.content.size() <= this.thumbsPerPage*2) {
            this.pagesDisplayed = 2;
        }
        this.segments = new struct.SegmentedList(this.pagesDisplayed, content.inGroupsOf(this.thumbsPerPage));
    },

    start: function(atItem) {
        
        if(this.content.size() <= this.thumbsPerPage) {
            // only 1 page.. disable previous/next navigation
            view.Carousel.disableNavigation();
        }
        
        if(atItem) {
            var atPage = this.segments.getList().find(
                function(page){
                    return page.include(atItem);
                }
            );
            this.segments.setCurrentSegmentByItem(atPage);
        }
        this.segments.prev();
        this.write();
    },
    
    next: function() {
        this._navigate(1);
    },
    
    prev: function() {
        this._navigate(-1);
    },
    
    write: function() {
        view.slideViewer.clear();
        
        this.segments.current().items.each(
            function(segment) {
                var pageElem = this._newPage(segment);
                view.slideViewer.push(pageElem);                
            }.bind(this)
        );
    },
    
    _newPage: function(segment) {
        var elem = new Element('DIV', { 'class': 'list_view_page' });
        if(segment) {
            segment.each(
                function(obj) {
                    if(!obj) return; // TODO: use new list method without nulls
                    elem.insert(
                        new Element('A')
                            .insert(
                                new Element('IMG', { src: obj.thumb })
                             )
                            .insert(obj.desc)
                            .observe('click',
                                function(evt) {
                                    view.Carousel.activateView(view.Detail, obj);
                                }
                            )
                    )
                }
            );
        }
        return elem;
    },
    
    _navigate: function(by) {
        if(view.Carousel.isNavigating()) return;
        view.Carousel.setNavigating(true);
        var nextSeg = this.segments[(by > 0 ? 'next' : 'prev')]();
        var newPage = this._newPage(nextSeg.items[(by > 0 ? 'last' : 'first')]());
        view.slideViewer[(by > 0 ? 'push' : 'unshift')](newPage);
        view.slideViewer.navigate(by,
            function(){
                view.slideViewer[(by > 0 ? 'shift' : 'pop')]();
                view.Carousel.setNavigating(false);
            }.bind(this)
        );
    }
    
};


