var Sidebar = Class.create({
    
    initialize: function() {
        
        this.options = Object.extend({
            
            root: '/',

            backgroundLayer: 'bgTransparent',
            frame:           'collectionIMG',
            container:       'sidebarContent',
            mainContent:     'Main',
            
            toggleQuotationButton: 'toggleQuotesButton',
            togglePortfolioButton: 'togglePortfolioButton',
            
            closeButton: 'closeLayerButton',
            
            closeButtonLabelPortfolio: 'Hide Portfolio',
            closeButtonLabelQuotation: 'Hide Quotation',
            
            portfolioClassName: 'LayerPortfolio',
            quotationClassName: 'LayerQuotation',
            
            portfolioSizeContainer: 'portfolio_amount',
            quotationSizeContainer: 'quotes_amount',
            
            useEffects: true,
            effectOptions: {
                duration: .5,
                queue:    'end'
            }
        }, arguments[0] || {});
        
        this.background = $(this.options.backgroundLayer);
        this.frame      = $(this.options.frame);
        this.container  = $(this.options.container);
        
        this.portfolioContent = '';
        this.quotesContent = '';
        
        if($(this.options.toggleQuotationButton)) {
            $(this.options.toggleQuotationButton).setAttribute('href', 'javascript:void(0)');
            $(this.options.toggleQuotationButton).observe('click', function() { this.toggleLayer('quotation') }.bind(this));
        }
        
        if($(this.options.togglePortfolioButton)) {
            $(this.options.togglePortfolioButton).setAttribute('href', 'javascript:void(0)');
            $(this.options.togglePortfolioButton).observe('click', function() { this.toggleLayer('portfolio') }.bind(this));
        }
        
        if($(this.options.closeButton))
        $(this.options.closeButton).observe('click', this.hideLayer.bind(this));

        // Assume that bg and frame have equal dimensions
        this.initialLayerStyle = $H({
            width:       parseInt(this.frame.getStyle('width').sub('px', '')),
            marginLeft:  parseInt(this.frame.getStyle('margin-left').sub('px', ''))
        });
        
        this.frame.setStyle({ overflow: 'hidden' });
        
        this.reloadContents();
        this.hideLayer();
    },
    
    switchLayer: function(contentType) {
        
        var closeButtonLabelOptionsKey = 'closeButtonLabel' + contentType.substring(0, 1).toUpperCase() + contentType.substring(1).toLowerCase();
        
        this.frame.removeClassName($H(this.options).get(this.layerState.get('contentType') + 'ClassName'));
        this.frame.addClassName($H(this.options).get(contentType + 'ClassName'));
        
        $(this.options.closeButton).update($H(this.options).get(closeButtonLabelOptionsKey));
    },
    
    toggleLayer: function(contentType) {
        
        // if hidden->show
        this.checkLayerState();
        if(!this.layerState.get('visible')) {
            this.showLayer(contentType);

        } else {
            
            // currently visible
            // -> if same content type as requested -> hide
            if(contentType == this.layerState.get('contentType')) {
                this.hideLayer();
            } else {
                this.hidden = false;
                
                new PeriodicalExecuter(function(pe) {
                    if(this.hidden) {
                        pe.stop();
                        this.showLayer(contentType);
                    }
                }.bind(this), .1);
                
                this.hideLayer({ afterFinish: function() { this.hidden = true; }.bind(this) });
            }
        }
    },
    
    showLayer: function(contentType) {
        
        var options = Object.extend(this.options.effectOptions, arguments[0] || {});
        
        this.switchLayer(contentType);
        switch(contentType) {
            case 'portfolio':
                this.container.update(this.portfolioContent);
                break;
                
            case 'quotation':
                this.container.update(this.quotesContent);
                break;
        }
        
        // Set height to page height
        var toHeight = $(this.options.mainContent).getStyle('height');
        $A([this.background, this.container, this.frame]).invoke('setStyle', { minHeight: toHeight });


        if(this.options.useEffects) {
            var toMarginLeft = new String(this.initialLayerStyle.get('marginLeft')) + 'px';
            var toWidth      = new String(this.initialLayerStyle.get('width')) + 'px';

            new Effect.Parallel([
                 new Effect.Morph(this.background, { style: { marginLeft: toMarginLeft, width: toWidth }, sync: true }),
                 new Effect.Morph(this.frame, { style: { marginLeft: toMarginLeft, width: toWidth }, sync: true }),
                 
                 new Effect.Appear(this.background, { sync: true, to: 0.8 }),
                 new Effect.Appear(this.frame, { sync: true })
             ], options);
        } else {
            this.background.show();
            this.frame.show();
            
            if(options.afterFinish)
            options.afterFinish();
        }
    },
    
    hideLayer: function() {
        
        var options = Object.extend(this.options.effectOptions, arguments[0] || {});
        
        if(this.options.useEffects) {
            var toMarginLeft = (this.initialLayerStyle.get('marginLeft') + this.initialLayerStyle.get('width')) + 'px';
            
            new Effect.Parallel([
                new Effect.Morph(this.background, { style: { marginLeft: toMarginLeft, width: '0px' }, sync: true }),
                new Effect.Morph(this.frame, { style: { marginLeft: toMarginLeft, width: '0px' }, sync: true }),
                
                new Effect.Fade(this.background, { sync: true }),
                new Effect.Fade(this.frame, { sync: true })
            ], options);
        } else {
            this.background.hide();
            this.frame.hide();
            
            if(options.afterFinish)
            options.afterFinish();
        }
    },
    
    reloadContents: function() {
        
        var updateContainer = function() {
            this.checkLayerState();
            if(this.layerState.get('visible')) {
                this.showLayer(this.layerState.get('contentType'));
            }
            
        }.bind(this);
        
        // Reload quotes
        new Ajax.Request(this.options.root + 'products.php?getQuotes', {
            
            onSuccess: function(t, json) {
            
                if($(this.options.quotationSizeContainer)) {
                    if(json.size < 10) {
                        $(this.options.quotationSizeContainer).update('&nbsp;' + json.size);
                    } else {
                        $(this.options.quotationSizeContainer).update(json.size);
                    }
                }
            
                this.quotesContent = t.responseText;
                updateContainer();
                
            }.bind(this)
        });
        
        // Reload portfolio
        new Ajax.Request(this.options.root + 'products.php?getBookmarks', {
            
            onSuccess: function(t, json) {
            
                if($(this.options.portfolioSizeContainer)) {
                    if(json.size < 10) {
                        $(this.options.portfolioSizeContainer).update('&nbsp;' + json.size);
                    } else {
                        $(this.options.portfolioSizeContainer).update(json.size);
                    }
                }
            
                this.portfolioContent = t.responseText;
                updateContainer();
                
            }.bind(this)
        });
    },
    
    checkLayerState: function() {
        
        var currentContentType = null;
        if(this.frame.hasClassName(this.options.quotationClassName)) {
            currentContentType = 'quotation';
        } else {
            currentContentType = 'portfolio';
        }
        
        this.layerState = $H({
            visible:     (this.background.visible() && this.frame.visible()),
            contentType: currentContentType
        });
    },
    
    setCustomContent: function(content) {
        new Effect.Fade(this.container, { 
            duration: 0.5,
            
            afterFinish: function() {
                this.container.update(content);
                this.container.show();
            }.bind(this)
        
        });
    }
    
});