﻿Volvo.CWP.HoverBox = function(hoverElement, triggerElements, options) {
    this.hoverElement = hoverElement;
    this.triggerElements = Array.ensureArray(triggerElements);
    this.options = options;
    this.init();
};

Volvo.CWP.HoverBox.Position = { Above:0, Below:1 };

Volvo.CWP.HoverBox.prototype.init = function() {
    this.ensureOptionValues();
    this.onitemshowing = new YAHOO.util.CustomEvent('onitemshowing');
    this.onitemhiding = new YAHOO.util.CustomEvent('onitemhiding');
    mouseoverDelegate = Volvo.CWP.createDelegate(this, this.handleMouseover);
    mouseoutDelegate = Volvo.CWP.createDelegate(this, this.handleMouseout);
    for (var i = 0; i < this.triggerElements.length; i++) {
        this.triggerElements[i].onmouseover = mouseoverDelegate;
        this.triggerElements[i].onmouseout = mouseoutDelegate;
    }
    this.hoverElement.onmouseout = mouseoutDelegate;
    this.setPosition(this.hoverElement);
    this.active = false;
};

Volvo.CWP.HoverBox.prototype.handleMouseover = function(e) {
    this.mouseEngaged = true;
    this.showPopup();
};

Volvo.CWP.HoverBox.prototype.handleMouseout = function(e) {
    var exited = e && e.target || window.event.srcElement;
    var entered = e && e.relatedTarget || window.event.toElement;
    if (entered == null || this.triggerElements.contains(entered, function(a, b) { return Volvo.CWP.containsElement(a, b); })) {
        return;
    }
    if (Volvo.CWP.containsElement(this.hoverElement, entered)) {
        return;
    }
    this.mouseEngaged = false;
    window.setTimeout(Volvo.CWP.createDelegate(this, function() { if (!this.mouseEngaged) { this.hidePopup(); } }), 0);
};

Volvo.CWP.HoverBox.prototype.showPopup = function() {
    if (!this.active) {
        this.onitemshowing.fire({ popup: this.hoverElement });
        this.active = true;
        this.hoverElement.style.visibility = 'visible';
    }
};

Volvo.CWP.HoverBox.prototype.hidePopup = function() {
    if (this.active) {
        this.onitemhiding.fire({ popup: this.hoverElement });
        this.active = false;
        this.hoverElement.style.visibility = 'hidden';
    }
};

Volvo.CWP.HoverBox.prototype.setPosition = function(popup) {
    var pointer = $(popup).find('.' + this.options.pointerClass)[0];
    var anchor = this.options.anchor;
    //set x
    var xcontainer = this.options.xcontainer;
    var leftBound = $(xcontainer).offset().left + 10;
    var rightBound = leftBound + xcontainer.offsetWidth - 20;
    var anchor_x = $(anchor).offset().left;
    var popup_x = (anchor_x - leftBound) + ((anchor.offsetWidth - popup.offsetWidth) / 2);
    var pointer_x = (popup.offsetWidth - pointer.offsetWidth) / 2;
    while (popup_x < 10) {
        popup_x++;
        pointer_x--;
    }
    while (popup_x + popup.offsetWidth > xcontainer.offsetWidth - 10) {
        popup_x--;
        pointer_x++;
    }
    //set y
    //set y above
    var ycontainer = this.options.ycontainer;
    var upperBound = $(ycontainer).offset().top;
    var anchor_y = $(anchor).offset().top;
    var offset_y = anchor_y - upperBound;
    var popup_y = offset_y - popup.offsetHeight;
    var pointer_y = popup.offsetHeight - 1;
    pointer.className = this.options.pointerDownClass;
    //if default is above and no room above OR below and has room below, move below
    if ((this.options.defaultPosition == Volvo.CWP.HoverBox.Position.Above && upperBound + popup_y < 5) ||
        (this.options.defaultPosition == Volvo.CWP.HoverBox.Position.Below)) {
        pointer.className = this.options.pointerUpClass;
        popup_y = offset_y + anchor.offsetHeight;
        pointer_y = (pointer.offsetHeight * -1) + 1;
    }
    popup.style.left = popup_x + 'px';
    popup.style.top = popup_y + 'px';
    pointer.style.left = pointer_x + 'px';
    pointer.style.top = pointer_y + 'px';
};

Volvo.CWP.HoverBox.prototype.ensureOptionValues = function() {
    if (this.options.pointerClass == undefined) {
        this.options.pointerClass = 'popup-arrow';
    }
    if (this.options.pointerUpClass == undefined) {
        this.options.pointerUpClass = 'popup-arrow-up';
    }
    if (this.options.pointerDownClass == undefined) {
        this.options.pointerDownClass = 'popup-arrow-down';
    }
    if (this.options.xcontainer == undefined) {
        this.options.xcontainer = document.getElementsByTagName('body')[0];
    }
    if (this.options.ycontainer == undefined) {
        this.options.ycontainer = document.getElementsByTagName('body')[0];
    }
    if (this.options.anchor == undefined) {
        this.options.anchor = this.triggerElements[0];
    }
    if (this.options.defaultPosition == undefined) {
        this.options.defaultPosition = Volvo.CWP.HoverBox.Position.Above;
    }
};