﻿var DropDown = Class.create({ 
    initialize: function(options) {
        // Variables
        this.Options = options;
        this.showing = false;
        this.Timeout = 0;
        
        // Display Options
        this.Effect = options.effects;
        this.AlignLeft = options.align == null || options.align == 'left' ? true : false;
        this.Padding = options.padding || {top: 0, left:0, right:0};
        this.Shadow = null || options.shadow;
        this.MaxHeight = options.max || 300;
        
        // Close Options
        this.CloseOnClick = options.closeOnClick != null && options.closeOnClick;
        this.CloseOnMouseout = options.closeOnMouseout != null && options.closeOnMouseout;
        this.ShowOnMouseover = options.showOnMouseover != null && options.showOnMouseover;
        
        // Get Elements
        this.Trigger = $(options.trigger);
        this.BaseElement = options.baseElement == 'parent' ? this.Trigger.parentNode :         
            options.baseElement == 'self' ? this.Trigger : $(options.baseElement);        
        this.DisplayElement = $(options.displayElement);
        
        // Event Listeners
        this.hideListener = this.Hide.bindAsEventListener(this);
        this.showFinishListener = this.ShowFinish.bindAsEventListener(this);
        this.hideFinishListener = this.HideFinish.bindAsEventListener(this);
        
        this.HideDropDown = function(){ 
            clearTimeout(this.Timeout);
            this.DisplayElement.setStyle({display:'none'}); 
            if (this.Shadow && this.Shadow.obj){
                this.Shadow.obj.setStyle({display:'none'});
            }
        }.bind(this);
        
        // Go
        this.MakeTrigger();
    }, 
    // Creates trigger function and assigns Events
    MakeTrigger: function(){
        // Return if there's no trigger to make
        if (this.Trigger == null) 
            return;
        
        Event.observe(this.Trigger, 'click', this.TriggerClick.bind(this));
        if (this.ShowOnMouseover){        
            Event.observe(this.Trigger, 'mouseover', this.Show.bind(this));
            this.CloseOnMouseout = true;
        }
        var g = this;
        
        // If close on mouse out option is selected, assign events
        if (this.CloseOnMouseout){
            Event.observe(this.DisplayElement, 'mouseout', function(){g.Timeout = setTimeout(g.Hide.bind(g), 300);});
            Event.observe(this.BaseElement, 'mouseout', function(){g.Timeout = setTimeout(g.Hide.bind(g), 300);});
            Event.observe(this.DisplayElement, 'mouseover', function(){clearTimeout(g.Timeout);});
            Event.observe(this.BaseElement, 'mouseover', function(){clearTimeout(g.Timeout);});
            
            if (this.ShowOnMouseover){
                Event.observe(this.Trigger, 'mouseout', function(){g.Timeout = setTimeout(g.Hide.bind(g), 300);});
                Event.observe(this.Trigger, 'mouseover', function(){clearTimeout(g.Timeout);});
            }
        }
        
        // If close on click is selected, assign events
        if (!this.CloseOnClick)
            Event.observe(this.DisplayElement, 'click', this.Show.bind(this));
        
        // Assign Default Events
        Event.observe(this.BaseElement, 'click', function(){this.showing = true;});
        Event.observe(window, 'load', this.MoveDisplayElement.bind(this));
    },
    // Handles Clicking the Trigger element
    TriggerClick: function(){
        if (this.DisplayElement.getStyle('display') == 'block')
            this.Hide();
        else
            this.Show();    
    },
    // Moves display element to the body tag so positioning is correct
    MoveDisplayElement: function(){
        $(document.body).appendChild(this.DisplayElement); 
        if (this.Shadow != null){        
            var shadow = new Element('div').update('&nbsp;');
            shadow.setStyle({
                position: 'absolute',                
                opacity: this.Shadow.opacity,
                background: '#000000',
                display: 'none'
            });
            this.Shadow.obj = shadow;
            $(document.body).appendChild(shadow);
        }            
    },
    // Shows display element
    Show: function(){
        // Assign hide for clicking on the window
        Event.observe(document.body, 'click', this.hideListener);
        
        // Run Functions
        this.ShowBegin();
        
        // Get Baseelement postition
        var pos = this.BaseElement.cumulativeOffset();
        
        // Get Effects
        var hasEffect = this.Effect != null && this.Effect.show != 'none' && this.Effect.show != null && this.DisplayElement.getStyle('display') == 'none';
        
        // Find if we need to align the popup box to the right of the base element
        var anchorRight = pos.left + this.DisplayElement.getWidth() > document.viewport.getWidth() || !this.AlignLeft;
        
        if (this.DisplayElement.getHeight() > this.MaxHeight)
            this.DisplayElement.setStyle({ height: this.MaxHeight + 'px', overflow: 'auto'});               
        // Assign Styles
        this.DisplayElement.setStyle({
            position: 'absolute',
            top: pos.top + this.BaseElement.getHeight() + this.Padding.top + 'px',
            display: 'none',
            zIndex: 1000
        });
        
        // Assign correct left/right values
        if (this.AlignLeft) {
            this.DisplayElement.setStyle({
                left: anchorRight ? pos.left + this.BaseElement.getWidth() - this.DisplayElement.getWidth() + this.Padding.left + 'px' : pos.left + this.Padding.left + 'px'
            });
        } else {
            this.DisplayElement.setStyle({
                right: anchorRight ? 
                    document.viewport.getWidth() - (pos.left + this.BaseElement.getWidth()) + this.Padding.right + 'px' : 
                    document.viewport.getWidth() - (pos.left + this.DisplayElement.getWidth()) + this.Padding.right + 'px'
            });
        }
        this.showing = true;
        if (hasEffect)
            Effect.toggle(this.DisplayElement, this.Effect.show, {duration: this.Effect.duration, afterFinish: this.showFinishListener});
        else {
            this.DisplayElement.setStyle({display: 'block'});
            this.ShowFinish();
       }
    },
    ResizeShadow: function(){
        this.ShowShadow();
    },
    // Displays Shadow
    ShowShadow: function(){
        var pos = this.DisplayElement.cumulativeOffset();
        if (pos.top == 0 && pos.left == 0) return;        
        this.Shadow.obj.setStyle({
            top: pos.top + this.Shadow.offset + 'px',
            left: pos.left + this.Shadow.offset + 'px',
            width: this.DisplayElement.getWidth() + 'px',
            height: this.DisplayElement.getHeight() + 'px',            
            display: 'block'
        });
    },
    // Fires before show starts
    ShowBegin: function(){
        if(this.Options.onShowBegin)
            this.Options.onShowBegin(this);
    },
    // Fires after show is complete
    ShowFinish: function(){
        //this.showing = false;
        
        if (this.Shadow != null && this.Shadow.obj)
            this.ShowShadow();
            
        if(this.Options.onShowFinish)
            this.Options.onShowFinish(this);
    },
    // Hides display element
    Close: function(){ this.Hide(); },
    Hide: function(){    
        // If showing do nothing
        if (this.showing) {this.showing = false; return;}
        
        if(this.Shadow != null && this.Shadow.obj != null)
            this.Shadow.obj.setStyle({display:'none'});
        
        // Find effect
        var hasEffect = this.Effect != null && this.Effect.hide != 'none' && this.Effect.hide != null && this.DisplayElement.getStyle('display') == 'block';
        if (hasEffect)
            Effect.toggle(this.DisplayElement, this.Effect.hide, {duration:this.Effect.duration, afterFinish: this.hideFinishListener});
        else {
            this.DisplayElement.setStyle({ display: !hasEffect ? 'none' : 'block' });
            this.HideFinish();
        }
            
        // Clear window click event
        Event.stopObserving(document.body, 'click', this.hideListener);
    },
    HideFinish: function(){
        if(this.Options.onHideFinish)
            this.Options.onHideFinish(this);
    }
});

var UserDropDown = Class.create(DropDown, {
    initialize: function($super, userId){
        $super({
            trigger: 'userDropDown_Trigger_' + userId,
            baseElement: 'parent',
            displayElement: 'userDropDown_' + userId,
            closeOnClick: false,
            align: 'right',
            padding: {top: 1, left: 0, right: 0},
            shadow: {opacity: .2, offset: 2},
            effects: {
                show: 'blind',
                hide: 'none',
                duration: .2
            },
            onShowBegin: function(t){
                t.Trigger.addClassName('userDropDown_Over');
            },        
            onShowFinish: function(t){          
            },
            onHideFinish: function(t){
                t.Trigger.removeClassName('userDropDown_Over');
            }        
        });
    }
});

var PickDeleter = Class.create(DropDown, {
    initialize: function($super, pickId){
        $super({
            trigger: 'pick_games_deletePick' + pickId,
            baseElement: 'parent',
            displayElement: 'pick_games_deletePick' + pickId + '_dd',
            closeOnClick: false,
            align: 'right',
            padding: { top: 1, left: 0, right: 0 },
            shadow: { opacity: .2, offset: .2 },
            effects: {
                show: 'blind',
                hide: 'none',
                duration: .2
            },
            onShowBegin: function(t){
                $(t.Trigger).addClassName('deleteOn');
            }, 
            onShowFinish: function(t){
                $(this.displayElement).select('input.reasonBox')[0].focus();
            },
            onHideFinish: function(t){
                $(t.Trigger).removeClassName('deleteOn');
            } 
        });
    }
});