/**
 * @fileOverview
 * @description <p>Miscellaneous utilities and helpers for use across projects.</p>
 * @author <a href="mailto:ludvig@urbantalk.se">Ludvig Svenonius</a>
 */

window.element_activators = [];

function activate_elements(element) {
    window.element_activators.each(function (element_activator) {
        element_activator(element);
    });
}

window.addEvent('domready', function () {
    activate_elements($(document.body));
});

/**
 * @namespace <p>Site extensions of MooTools' <a target="_BLANK" href="http://mootools.net/docs/core/Element/Element#Element">Element</a> class.</p>
 * @name Element
 */

Element.implement(
    /** @lends Element */
    {
        /**
         * <p>Complement method to MooTools <a target="_BLANK" href="http://mootools.net/docs/core/Element/Element#Element:toQueryString">Element.toQueryString</a> - sets descendant input field values to values given in provided dictionary or query string.</p>
         * @param {dictionary} values <p>Dictionary of key/value pairs to set form fields to.</p>
         */
        setInputValues : function (values) {
            if (typeof values === 'string') values = values.parseQueryString();
            
            this.getElements('input').each(function (input_element) {
                if (input_element.get('type') === 'checkbox') {
                    if (values[input_element.get('name')]) {
                        input_element.checked = true;
                    }
                    else {
                        input_element.checked = false;
                    }
                }
                if (values[input_element.get('name')]) {
                    input_element.value = values[input_element.get('name')];
                }
            });
            
            this.getElements('select').each(function (combo_box) {
                combo_box.getChildren('option').each(function (option) {
                    if (values[combo_box.get('name')] === option.get('value')) {
                        option.selected = true;
                    }
                });
            });
        },
        
        /**
         * <p>Attempts to scroll <i>this</i> so <i>element</i> is displayed in the center of <i>this</i>. Assumes that <i>this</i> is a viewport element against a single larger child element, which in turn is a parent of <i>element</i>. Does nothing otherwise. Note: <i>this</i> will not scroll across the edge of the child element, but will stop at the edge even if <i>element</i> is not entirely centered.</p>
         * <p>Dispatched events:</p>
         * <table>
         *   <tr><th>Name</th><th>Fire condition</th></tr>
         *   <tr><th style="text-align: left; vertical-align: top;"><p>scrolled</p></th><td><p>Fired if the method call causes <i>this</i> to scroll.</p></td></tr>
         *   <tr><th colspan="2">Below events are only fired if </tr>
         *   <tr><th style="text-align: left; vertical-align: top;"><p>leftEdgeTouched</p></th><td><p>Fired if the scroll resulting from the call causes <i>this</i> to scroll all the way to the left edge of its child element.</p></td></tr>
         *   <tr><th style="text-align: left; vertical-align: top;"><p>rightEdgeTouched</p></th><td><p>Fired if the scroll resulting from the call causes <i>this</i> to scroll all the way to the right edge of its child element.</p></td></tr>
         *   <tr><th style="text-align: left; vertical-align: top;"><p>topEdgeTouched</p></th><td><p>Fired if the scroll resulting from the call causes <i>this</i> to scroll all the way to the top edge of its child element.</p></td></tr>
         *   <tr><th style="text-align: left; vertical-align: top;"><p>bottomEdgeTouched</p></th><td><p>Fired if the scroll resulting from the call causes <i>this</i> to scroll all the way to the bottom edge of its child element.</p></td></tr>
         *   <tr><th style="text-align: left; vertical-align: top;"><p>leftEdgeDeparted</p></th><td><p>Fired if the scroll resulting from the call causes <i>this</i> to scroll away from the left edge of its child element.</p></td></tr>
         *   <tr><th style="text-align: left; vertical-align: top;"><p>rightEdgeDeparted</p></th><td><p>Fired if the scroll resulting from the call causes <i>this</i> to scroll away from the right edge of its child element.</p></td></tr>
         *   <tr><th style="text-align: left; vertical-align: top;"><p>topEdgeDeparted</p></th><td><p>Fired if the scroll resulting from the call causes <i>this</i> to scroll away from the top edge of its child element.</p></td></tr>
         *   <tr><th style="text-align: left; vertical-align: top;"><p>bottomEdgeDeparted</p></th><td><p>Fired if the scroll resulting from the call causes <i>this</i> to scroll away from the bottom edge of its child element.</p></td></tr>
         * </table>
         * @param {Element} element <p>The element to scroll to.</p>
         * @param {dictionary} fx_options <p>MooTools <a target="_BLANK" href="http://mootools.net/docs/core/Fx/Fx">Fx</a> options dictionary, for the effect to be used for the scrolling. If omitted scrolling is instantaneous. (optional)</p>
         * @param {boolean} cross_boundaries <p>Whether scrolling should stop at content pane edges (in which case an event will be fired). This is the default behavior. If <i>true</i> is given, the element will be unconditionally centered and no "edge touched events" will be generated.</p>
         */
        centerOnElement : function (element, options) {
            var content_pane, scroll_vertically, scroll_horizontally, top, left, content_pane_position, scroll_fx, left_edge_touched_after, right_edge_touched_after, top_edge_touched_after, bottom_edge_touched_before, left_edge_touched_before, right_edge_touched_before, top_edge_touched_before, bottom_edge_touched_before, fx_options, cross_boundaries, new_pos;
            
            if (options) {
                fx_options = options.fx_options;
            }
            else {
                options    = {};
                fx_options = null;
            }
            
            //if (this.getChildren().length !== 1) return false;
            
            content_pane = this.getChildren()[0];
            
            if (content_pane === element) {
                options.cross_boundaries = true;
            }
            
            if (options.cross_boundaries) {
                scroll_horizontally = true;
                scroll_vertically   = true;
            }
            else {
                scroll_horizontally = (this.getSize().x < content_pane.getSize().x);
                scroll_vertically   = (this.getSize().y < content_pane.getSize().y);
            }
            
            if (options) {
                scroll_horizontally = scroll_horizontally && (options.scroll_horizontally !== false);
                scroll_vertically   = scroll_vertically   && (options.scroll_vertically   !== false);
            }
                
            if (!scroll_horizontally && !scroll_vertically) return false;
            
            left_edge_touched_before = (content_pane.getStyle('left').toInt() === 0);
            top_edge_touched_before  = (content_pane.getStyle('top').toInt()  === 0);
            
            right_edge_touched_before  = (content_pane.getStyle('left').toInt() === (this.getSize().x - content_pane.getSize().x))
            bottom_edge_touched_before = (content_pane.getStyle('top').toInt()  === (this.getSize().y - content_pane.getSize().y))
            
            left_edge_touched_after   = false;
            top_edge_touched_after    = false;
            right_edge_touched_after  = false;
            bottom_edge_touched_after = false;
            
            content_pane_position = content_pane.getPosition(this);
            
            if (scroll_horizontally) {
                left = -(element.getPosition(content_pane).x + parseInt(element.getSize().x / 2.0, 10) - parseInt(this.getSize().x / 2.0, 10))
                
                if (!options.cross_boundaries ) {
                    if (left >= 0) {
                        left = 0;
                        left_edge_touched_after = true;
                    }
                    
                    if (left + content_pane.getSize().x <= this.getSize().x) {
                        left = this.getSize().x - content_pane.getSize().x;
                        right_edge_touched_after = true;
                    }
                }
            }
        
            if (scroll_vertically) {
                top  = -(element.getPosition(content_pane).y + parseInt(element.getSize().y / 2.0, 10) - parseInt(this.getSize().y / 2.0, 10))
                
                if (!options.cross_boundaries) {		
                    if (top >= 0) {
                        top = 0;
                        top_edge_touched_after = true;
                    }
                    
                    if (top + content_pane.getSize().y <= this.getSize().y) {
                        top = this.getSize().y - content_pane.getSize().y;
                        bottom_edge_touched_after = true;
                    }
                }
            }
            
            if (!scroll_horizontally && (top  === content_pane_position.y)) return false;
            if (!scroll_vertically   && (left === content_pane_position.x)) return false;
            if ((left === content_pane_position.x) && (top === content_pane_position.y)) return false;
            
            this.fireEvent('scrolled');
            
            if (!options.cross_boundaries) {
                if (!left_edge_touched_before && left_edge_touched_after) {
                    this.fireEvent('leftEdgeTouched');
                }
                
                if (!right_edge_touched_before && right_edge_touched_after) {
                    this.fireEvent('rightEdgeTouched');
                }
                
                if (!top_edge_touched_before && top_edge_touched_after) {
                    this.fireEvent('topEdgeTouched');
                }
                
                if (!bottom_edge_touched_before && bottom_edge_touched_after) {
                    this.fireEvent('bottomEdgeTouched');
                }            
                
                if (left_edge_touched_before && !left_edge_touched_after) {
                    this.fireEvent('leftEdgeDeparted');
                }
                
                if (right_edge_touched_before && !right_edge_touched_after) {
                    this.fireEvent('rightEdgeDeparted');
                }
                
                if (top_edge_touched_before && !top_edge_touched_after) {
                    this.fireEvent('topEdgeDeparted');
                }
                
                if (bottom_edge_touched_before && !bottom_edge_touched_after) {
                    this.fireEvent('bottomEdgeDeparted');
                }
            }
            
            scroll_fx = new Fx.Morph(content_pane, fx_options);
            
            new_pos = {};
            
            if (scroll_vertically) {
                new_pos.top = top + 'px';
                content_pane.setStyle('top', content_pane_position.y + 'px');
            }
            
            if (scroll_horizontally) {
                new_pos.left = left + 'px';
                content_pane.setStyle('left', content_pane_position.x + 'px');
            }
            
            if (fx_options) {
                scroll_fx.start(new_pos);
            }
            else {
                scroll_fx.set(new_pos);
            }
            
            return true;
        },
        
        /**
         * <p>Attempts to scroll <i>this</i> so <i>element</i> is fully visible. Assumes that <i>this</i> is a viewport element against a single larger child element, which in turn is a parent of <i>element</i>. Does nothing otherwise.</p>
         * <p>Dispatched events:</p>
         * <table>
         *   <tr><th>Name</th><th>Fire condition</th></tr>
         *   <tr><th style="text-align: left; vertical-align: top;"><p>scrolled</p></th><td><p>Fired if the method call causes <i>this</i> to scroll.</p></td></tr>
         *   <tr><th style="text-align: left; vertical-align: top;"><p>leftEdgeTouched</p></th><td><p>Fired if the scroll resulting from the call causes <i>this</i> to scroll all the way to the left edge of its child element.</p></td></tr>
         *   <tr><th style="text-align: left; vertical-align: top;"><p>rightEdgeTouched</p></th><td><p>Fired if the scroll resulting from the call causes <i>this</i> to scroll all the way to the right edge of its child element.</p></td></tr>
         *   <tr><th style="text-align: left; vertical-align: top;"><p>topEdgeTouched</p></th><td><p>Fired if the scroll resulting from the call causes <i>this</i> to scroll all the way to the top edge of its child element.</p></td></tr>
         *   <tr><th style="text-align: left; vertical-align: top;"><p>bottomEdgeTouched</p></th><td><p>Fired if the scroll resulting from the call causes <i>this</i> to scroll all the way to the bottom edge of its child element.</p></td></tr>
         * </table>
         * @param {Element} element <p>The element to scroll to.</p>
         * @param {dictionary} fx_options <p>MooTools <a target="_BLANK" href="http://mootools.net/docs/core/Fx/Fx">Fx</a> options dictionary, for the effect to be used for the scrolling. If omitted scrolling is instantaneous. (optional)</p>
         */
        scrollToElement : function (element, options) {
            var content_pane, scroll_vertically, scroll_horizontally, top, left, content_pane_position, scroll_fx, left_edge_touched_after, right_edge_touched_after, top_edge_touched_after, bottom_edge_touched_before, left_edge_touched_before, right_edge_touched_before, top_edge_touched_before, bottom_edge_touched_before, fx_options, cross_boundaries, new_pos;
            
            if (options) {
                fx_options = options.fx_options;
            }
            else {
                options    = {};
                fx_options = null;
            }
            
            //if (this.getChildren().length !== 1) return false;
            
            content_pane = this.getChildren()[0];
            
            scroll_horizontally = (this.getSize().x < content_pane.getSize().x);
            scroll_vertically   = (this.getSize().y < content_pane.getSize().y);
            
            if (options) {
                scroll_horizontally = scroll_horizontally && (options.scroll_horizontally !== false);
                scroll_vertically   = scroll_vertically   && (options.scroll_vertically   !== false);
            }
                
            if (!scroll_horizontally && !scroll_vertically) return false;
            
            left_edge_touched_before = (content_pane.getStyle('left').toInt() === 0);
            top_edge_touched_before  = (content_pane.getStyle('top').toInt()  === 0);
            
            right_edge_touched_before  = (content_pane.getStyle('left').toInt() === (this.getSize().x - content_pane.getSize().x))
            bottom_edge_touched_before = (content_pane.getStyle('top').toInt()  === (this.getSize().y - content_pane.getSize().y))
            
            left_edge_touched_after   = false;
            top_edge_touched_after    = false;
            right_edge_touched_after  = false;
            bottom_edge_touched_after = false;
        
            content_pane_position = content_pane.getPosition(this);
                
            if (scroll_horizontally) {
                left = content_pane_position.x;
                
                if (left + element.getPosition(content_pane).x < 0) {
                    left = -element.getPosition(content_pane).x
                }
                else if (left + element.getPosition(content_pane).x + element.getSize().x > this.getSize().x) {
                    left = this.getSize().x - element.getPosition(content_pane).x - element.getSize().x;
                }
            }
            
            if (scroll_vertically) {
                top = content_pane_position.y;
                
                if (top + element.getPosition(content_pane).y < 0) {
                    top = -element.getPosition(content_pane).y
                }
                else if (top + element.getPosition(content_pane).y + element.getSize().y > this.getSize().y) {
                    top = this.getSize().y - element.getPosition(content_pane).y - element.getSize().y;
                }
            }
            
            if (!scroll_horizontally && (top  === content_pane_position.y)) return false;
            if (!scroll_vertically   && (left === content_pane_position.x)) return false;
            if ((left === content_pane_position.x) && (top === content_pane_position.y)) return false;
            
            this.fireEvent('scrolled');
            
            if (!left_edge_touched_before && left_edge_touched_after) {
                this.fireEvent('leftEdgeTouched');
            }
            
            if (!right_edge_touched_before && right_edge_touched_after) {
                this.fireEvent('rightEdgeTouched');
            }
            
            if (!top_edge_touched_before && top_edge_touched_after) {
                this.fireEvent('topEdgeTouched');
            }
            
            if (!bottom_edge_touched_before && bottom_edge_touched_after) {
                this.fireEvent('bottomEdgeTouched');
            }            
            
            if (left_edge_touched_before && !left_edge_touched_after) {
                this.fireEvent('leftEdgeDeparted');
            }
            
            if (right_edge_touched_before && !right_edge_touched_after) {
                this.fireEvent('rightEdgeDeparted');
            }
            
            if (top_edge_touched_before && !top_edge_touched_after) {
                this.fireEvent('topEdgeDeparted');
            }
            
            if (bottom_edge_touched_before && !bottom_edge_touched_after) {
                this.fireEvent('bottomEdgeDeparted');
            }
            
            scroll_fx = new Fx.Morph(content_pane, fx_options);
            
            new_pos = {};
            
            if (scroll_vertically) {
                new_pos.top = top + 'px';
                content_pane.setStyle('top', content_pane_position.y + 'px');
            }
            
            if (scroll_horizontally) {
                new_pos.left = left + 'px';
                content_pane.setStyle('left', content_pane_position.x + 'px');
            }
            
            if (fx_options) {
                scroll_fx.start(new_pos);
            }
            else {
                scroll_fx.set(new_pos);
            }
            
            return true;
        },
        
        /**
         * <p>"Hibernates" an element by emptying it of its innerHTML and storing it for later reinjection. Useful for deactivation of background flash animations or movie players that might interfere somehow with a modal opened on top.</p>
         */
        hibernate : function () {
            this.store('_hibernate_innerhtml', this.get('html'));
            this.empty();
            this.addClass('hibernated_element');
        },
        
        /**
         * <p>Reactivates a previously hibernated element.</p>
         */
        dehibernate : function () {
            this.set('html', this.retrieve('_hibernate_innerhtml'));
            this.set('_hibernate_innerhtml', null);
            this.removeClass('hibernated_element');
        }
    }
);


var WindowResizeLayoutUpdater = new Class({
    Implements: [Events, Class.Occlude],
    
    property: 'windowresizelayoutupdater',
    
    initialize: function () {
        this.element = document.body;
        
        if (this.occlude()) {
            return this.occluded.occludedInitialize();
        }
        
        return this.occludedInitialize();
    },
    
    occludedInitialize: function () {
        this.delay = 10;
        this.events_fired = 0;
        
        this._onWindowResize = function (event) {
            this.onWindowResize.bind(this, event)();
        }.bind(this);
        
        window.addEvent('resize', this._onWindowResize);
    },
    
    onWindowResize: function () {
        this.fireEvent('updatelayout');
        this.dispatchAndQueue.delay(this, this.delay);
    },
    
    dispatchAndQueue: function () {
        if (this.events_fired < 8) {
            this.delay *= 2;
            this.events_fired += 1;
            
            this.fireEvent('updatelayout');
            
            this.dispatchAndQueue.delay(this, this.delay);
        }
        else {
            this.delay = 10;
            this.events_fired = 0;
        }
    }
});


var _updater_func = function (event) {
    $$('.mask').each(function (mask_element) {
        mask_element.setStyles({
            'width'  : window.getSize().x + 'px',
            'height' : window.getSize().y + 'px'
        });
    });
    
    $$('.gallery_image_container').each(function (mask_element) {
        mask_element.setStyles({
            'width'  : window.getSize().x + 'px',
            'height' : window.getSize().y -74 -44 + 'px'
        });
    });
    
    
    $$('.StickyWinInstance').each(function (stickywin_element) {
        stickywin_element.setStyles({
            'left' : (window.getSize().x - stickywin_element.getSize().x) / 2 + 'px',
            'top'  : (window.getSize().y - stickywin_element.getSize().y) / 2 + 'px'
        });
    });
}

window.addEvent('domready', _updater_func);
window.addEvent('resize'  , _updater_func);

var MultiGATracker = new Class({
    initialize: function (tracker_ids) {
        this.trackers = tracker_ids.map(function (item, index, array) {
            return _gat._getTracker(item);
        });
    },
    
    _trackEvent: function (category, action, label) {
        this.trackers.each(function (tracker) {
            tracker._trackEvent(category, action, label);
        });
    },
    
    _trackPageview: function (uri) {
        this.trackers.each(function (tracker) {	
            tracker._trackPageview(uri);
        });
    }
});

//Kollar om iPad används
var is_ipad = navigator.userAgent.match(/iPad/i) != null;

var ActivateStickyWinCloseButton = function () {
    $$(".closeSticky").each(function (el) {
        el.addEvent('click', function () {
            var mc = el.getParent('#modal_chooser');
            mc.retrieve('stickywin').hide();
            mc.retrieve('stickywin').destroy();
            return false;
        });
    });
}

// Uppdaterar alla #modal_chooser (Stickywin.modal) om de är större än fönsterstorleken
var ResizeStickyWinInstance = function (event) {
    $$('#modal_chooser').each(function (stickywin_instance) {
        if(stickywin_instance.getStyle('top').slice(0, -2) < 10){
            stickywin_instance.setStyles({
               'top':           '10px',
               'bottom':        '10px',
               'overflow-y':    'scroll',
               'overflow-x':    'hidden'
            });
        }
        if(stickywin_instance.getStyle('top').slice(0, -2) == 10){
            if(stickywin_instance.getElementById('close_modal_button')){
                stickywin_instance.getElementById('close_modal_button').setStyles({
                    'position': 'fixed',
                    'top': '2px',
                    'left': (parseInt(stickywin_instance.getStyle('left').slice(0, -2)) -7) + 'px'
                });
            }
        }
    });
}

window.addEvent('resize', ResizeStickyWinInstance);

var ForceRepositionModalChooser = function () {
    window.fireEvent('resize');
}
