var ActionZone = 
{
    _az: null,
    _op: null,
    _od: null,
    _triggerOffset: 0,
    _isFloating: false,
    
    init: function()
    {
        this._az = $A($$('.zone-action')).reduce();
        if(this._az)
        {
            this._az = $(this._az);
            this._op = this._az.positionedOffset();
            this._triggerOffset = this._op[1];
            document.observe('scroll', this._scroll.bindAsEventListener(this));
        }
    },
    
    _scroll: function(e)
    {
        var so = document.viewport.getScrollOffsets()
        if(this._triggerOffset < so[1])
        {
            if(!this._isFloating)
            {
                var a = $('zone-action-floating');
                var n = a.down();
                while(this._az.childNodes.length)
                {
                    n.appendChild(this._az.childNodes[0]);
                }
                this._isFloating = true;
                a.show();
            }
            
        }
        else
        {
            if(this._isFloating)
            {
                var a = $('zone-action-floating');
                var n = a.down();
                while(n.childNodes.length)
                {
                    this._az.appendChild(n.childNodes[0]);
                }
                this._isFloating = false;
                a.hide();
            }
        }
    },
    
    getTriggerOffset: function()
    {
        return this._triggerOffset;
    },
    
    setTriggerOffset: function(offset)
    {
      this._triggerOffset = offset;  
    }
}

document.observe('dom:loaded', ActionZone.init.bind(ActionZone));

var ListHelper = 
{
    init: function()
    {
        if(Prototype.Browser.IE) // If browser is IE, compensate for lack of :hover on any element
            $A($$('table.list tbody tr')).invoke('observe', 'mouseover', this._rowMouseOver.bindAsEventListener(this)).invoke('observe', 'mouseout', this._rowMouseOut.bindAsEventListener(this));
    },
    
    _rowMouseOver: function(e)
    {
        var r = e.element().up('tr');
        r.addClassName('hover');
    },
    
    _rowMouseOut: function(e)
    {
        var r = e.element().up('tr');
        r.removeClassName('hover');
    }
}

document.observe('dom:loaded', ListHelper.init.bind(ListHelper));

var FullscreenManager =
{
    _current: null,
    _expandables: $H(),
    _handler: null,
    _actionsTriggerOffset: 0,
    
    init: function()
    {
        $A($$('.expandable')).each(function(exp)
        {
            exp = $(exp);
            this._expandables.set(exp.identify(), exp);
        }.bind(this));
        this._handler = this.collapse.bindAsEventListener(this);
    },
    
    chooseExpandable: function()
    {
        var str = '<p>Choose expandable: <select id="expandable">';
        this._expandables.each(function(exp)
        {
            str += '<option value="'+exp[0]+'">'+exp[1].title+'</option>';            
        })
        str += '</select></p><div>';
        str += '<a href="#" onclick="FullscreenManager.expand($F(\'expandable\')); Modalbox.hide(); return false;" class="button"><span>Go fullscreen</span></a>';
        str += '<a href="#" onclick="Modalbox.hide(); return false;" class="button"><span>Cancel</span></a>';
        str += '</div>';
        Modalbox.show(str);
    },
    
    expand: function(id)
    {
        var exp = this._expandables.get(id);
        exp.addClassName('expanded');
        this._current = exp;
        document.observe('keypress', this._handler);
        this._actionsTriggerOffset = ActionZone.getTriggerOffset();
        ActionZone.setTriggerOffset(0);
    },
    
    collapse: function(e)
    {
        console.debug(e);
        if(e && e.keyCode != 27)
            return;
        document.stopObserving('keypress', this._handler);
        this._current.removeClassName('expanded');
        this._current = null;
        ActionZone.setTriggerOffset(this._actionsTriggerOffset);
    },
    
    isExpanded: function()
    {
        return (this._current != null);
    }
}

document.observe('dom:loaded', FullscreenManager.init.bind(FullscreenManager));

/* Prompt bar from http://alexle.net */
var Prompt =
{
    autoHideTime: 2000,
    _timer: null,
    _effect: null,
    
    _cancelHide: function()
    {
        if(this._timer)
            clearTimeout(this._timer);
        this._timer = null;
    },
    
    display: function(msg, options)
    {
        this._cancelHide();
        $('prompt_message').innerHTML = msg;
        Prompt.show();
        
        if( options && options.autoHide )
            this._timer = setTimeout('Prompt.hide()', options.autoHideTime || Prompt.autoHideTime );
    },
    
    working: function(msg, options)
    {
        msg = '<img src="'+Globule.adminRoot+'/images/progress.gif"/>&nbsp;&nbsp;' + msg;
        Prompt.display(msg, options);
    },
    
    _center: function()
    {
        $('prompt').style.left = ( ( document.viewport.getWidth() - parseInt( $('prompt').offsetWidth ) ) / 2 ) + 'px' ;
    },
    
    show: function()
    {
        this._cancelHide();
        Prompt._center();
        if(this._effect)
            this._effect.cancel();
        this._effect = new Effect.Move ($('prompt'),{ x: parseInt( $('prompt').style.left ), y: 0, mode: 'absolute', duration: 0.2 });
    },
    
    hide: function( msg)
    {
        this._cancelHide();
        if(this._effect)
            this._effect.cancel();
        this._effect = new Effect.Move ($('prompt'),{ x: parseInt( $('prompt').style.left ), y: -30, mode: 'absolute', duration: 0.1 });
    }
}

var Tree = Class.create(
{
    _current: null,
    _options: {
        nodePrefix: 'node-',
        nodeToggled: null,
        nodeSelected: null
    },
    
    _ecache: $H(),
    
    initialize: function(container)
    {
        var nodes = $A($(container).getElementsByTagName('li'));
        nodes.each(function(n)
        {
            n = $(n);
            var img = n.down('img');
            var span = n.down('span');
            var ul = n.down('ul');
            if(!img.hasClassName('noclose') && ul.immediateDescendants().length > 0)
            {
                var f = this._toggleNode.bind(this, img, ul);
                this._ecache.set(img.identify(), f);
                img.observe('click', f);
            }
            else
                img.addClassName('leaf');
            span.observe('click', this._selectNode.bind(this, span));
        }.bind(this));

        this._options = Object.extend(this._options, arguments[1] || {});
        
        var p = new String(document.location).toQueryParams();
        if(p.open)
        {
            var n = $(this._options.nodePrefix+p.open);
            while(n)
            {
                var img = n.previous('img');
                if(!img.hasClassName('leaf') && !img.hasClassName('open'))
                    this._toggleNode(img, n.next('ul'));
                n = n.up('ul').previous('span');
            }
        }
        
        if(p.select)
        {
            var n = $(this._options.nodePrefix+p.select);
            if(n)
                this._selectNode(n);
        }
    },
    
    _toggleNode: function(trigger, child)
    {
        if(this._options.nodeToggled && !this._options.nodeToggled(trigger, child))
            return;
        trigger.toggleClassName('open');
        child.toggle();
    },
    
    _selectNode: function(node)
    {
        if(this._options.nodeSelected && !this._options.nodeSelected(node, this._current))
            return;
        if(this._current)
            this._current.removeClassName('selected');
        if(node == this._current)
            this._current = null;
        else
        {
            node.addClassName('selected');
            this._current = node;
        }
    },
    
    moveNode: function(node, newChild)
    {
        var newContainer = node.next('ul');
        var newChild = newChild.up();
        var previousContainer = newChild.up();
        
        newContainer.appendChild(newChild);
        var n = newContainer.previous('img')
        if(n.hasClassName('leaf'))
        {
            n.removeClassName('leaf');
            var f = this._toggleNode.bind(this, n, newContainer);
            this._ecache.set(n.identify(), f);
            n.observe('click', f);
        }
        
        if(previousContainer.immediateDescendants().length == 0)
        {
            n = previousContainer.previous('img');
            n.addClassName('leaf');
            n.stopObserving('click', this._ecache.get(n.identify()));
        }
    }
});

Object.extend(Modalbox, {
    _confirmCancelCallback: null,
    _confirmOKCallback: null,
    
    confirm: function(message, options)
    {
        var opt = 
        {
            slideDownDuration: .2,
            slideUpDuration: .2,
            resizeDuration: .1,
            title: 'Please confirm',
            cancelLabel: 'cancel',
            okLabel: 'ok',
            afterHide: this._confirmCancel.bind(this, true),
            cancelCallback: null,
            okCallback: null
        };

        opt = Object.extend(opt, options||{});
        
        this._confirmCancelCallback = opt.cancelCallback;
        this._confirmOKCallback = opt.okCallback;
        
        var str = '<p>'+message+'</p><div>';
        str += '<a href="#" onclick="Modalbox._confirmOK(); return false;" class="button"><span>'+opt.okLabel+'</span></a>';
        str += '<a href="#" onclick="Modalbox._confirmCancel(false); return false;" class="button"><span>'+opt.cancelLabel+'</span></a>';
        str += '</div>';
        this.show(str, opt);
    },
    
    _confirmOK: function()
    {
        this.options.cancelCallback = null;
        Modalbox.hide();

        if(this.options.okCallback)
            this.options.okCallback();
    },
    
    _confirmCancel: function(alreadyHidden)
    {
        if(!alreadyHidden)
            Modalbox.hide();
        if(this.options.cancelCallback)
            this.options.cancelCallback();
    }
});

Element.addMethods($A(['input','select','textarea']),{
    setValue: function(element, value)
    {
        element = $(element);
        if(element.tagName == 'TEXTAREA' || (element.tagName == 'INPUT' && (element.type == 'text' || element.type == 'hidden')))
            element.value = value;
        else if(element.tagName == 'SELECT')
        {
            for(var i = 0; i < element.options.length; i++)
            {
                if(element.options[i].value == value)
                    element.options[i].selected = true;
            }
        }
        else
            element.checked = value;
    }
});

var TableSort =
{
    _tables: $H(),
    _sortContent: [' &#x21D1;', ' &#x21D3;'],
    
    init: function(sortContent)
    {
        if(sortContent)
            this._sortContent = sortContent;
        var tbls = $A($$('table.sortable'));
        tbls.each(this._initTable.bind(this));
    },
    
    _initTable: function(table)
    {
        var f = $w(table.className).grep(/^sortform_/).reduce().substr(9);
        this._tables.set(table.identify(), f);
        var qp = new String(document.location).toQueryParams();
        var sort = ['','ASC'];
        if(qp.sort)
            sort = qp.sort.split(/,/);
        $A(table.select('thead tr th')).each(function(th)
        {
            $w($(th).className).each(function(c){
                if(c.startsWith('sort_'))
                {
                    var s = c.substr(5);
                    th.observe('click', this.sort.bindAsEventListener(this, s));
                    th.setStyle({cursor: 'pointer'});
                    if(sort[0] == s)
                    {
                        th.addClassName('sorted_'+sort[1].toLowerCase());
                        th.update(th.innerHTML+((sort[1]=='ASC')?this._sortContent[1]:this._sortContent[0]));
                    }
                }
            }.bind(this));
        }.bind(this));
    },
    
    sort: function(e, key)
    {
        var th = e.element();
        if(th.tagName.toLowerCase() != 'th')
            th = th.up('th');
        var t = th.up('table');
        var f = $(this._tables.get(t.identify()));
        
        var sortdir = 'ASC';
        if(th.hasClassName('sorted_asc'))
            sortdir = 'DESC';
        var sf = f.select('input[name=sort]').reduce();
        sf.value = key+','+sortdir;
        f.submit();
    }
};

