
var Popup = Class.create();

Popup.prototype = {

    /**
     * Class constructor, initializes the popup variables.
     *
     * The constructor takes either one or two parameters. The first one is
     * mandatory and it's the id-attribute for the popup-element. The second one
     * is an object with the popup settings, but it's not mandatory. Available
     * settings are:
     *
     * content  {element}       The content for the popup
     * width    {int}           The width of the popup in pixels
     * height   {int}           The height of the popup's content area in pixels
     * parent   {element}       The parent element of the popup element. The popup
     *                          will be placed under body-element, but the parent-setting
     *                          defines where in the page the popup should be
     *                          placed when it's created
     * title    {string}        The text in the title bar
     *
     * @param   {string}    elId    The id of the popup
     */
    initialize: function (elId) {

        this._elId      = elId;
        this._popup     = null;
        this._dragObj   = null;
        this._doResize  = false;
        this._bodyEl    = document.getElementsByTagName('body')[0];
        this._pos       = [];
        this._ghostRect = null;
        this._self      = this;
        this._titleBar  = null;
        this._contentArea = null;
        this._timer     = null;
        this._mousePos  = [];

        this._options = Object.extend({
            content:    '',
            width:      200,
            height:     300,
            parent:     this._bodyEl,
            title:      '-',
            okText:     'Ok',
            minWidth:   100,
            minHeight:  100
        }, arguments[1] || {});

        // events
        this.eventDrag = this._disableSelection.bindAsEventListener(this);
        this.eventSelectStart = this._disableSelection.bindAsEventListener(this);
        this.eventMouseMove = this._updateMousePos.bindAsEventListener(this);
        this.eventMouseDown = this._initResize.bindAsEventListener(this);
        this.eventMouseUp = this._endResize.bindAsEventListener(this);

        this._create();

    },


    /**
     * Displays the popup
     */
    show: function () {

        this._bodyEl.appendChild(this._popup);

        // make the popupwindow draggable
        this._dragObj = new Draggable(this._elId, {
            handle: 'popupTitleBar'
        });

        var position = Position.cumulativeOffset(this._options.parent);

        this._popup.style.left   = position[0] + 'px';
        this._popup.style.top    = position[1] + 'px';

        Element.show(this._popup);

    },

    // creates the popup element
    _create: function () {

        this._titleBar      = this._createTitleBar();
        this._contentArea   = this._createContentArea();

        this._popup = Builder.node('div', {
            className: 'popup',
            id: this._elId,
            style: 'width: ' + this._options.width + 'px; '
        }, [
            Builder.node('div', { className: 'popupSubContainer' }, [
                this._titleBar,
                this._contentArea
            ])
        ]);

        new Rounded(this._popup.firstChild, {
            radius: 4,
            headerBg: '#999999',
            borderColor: '#999999',
            contentBg: '#ededeb',
            footerBg: '#ededeb',
            corners: {
                topLeft: true,
                topRight: true,
                bottomLeft: false,
                bottomRight: false
            }
        });

        Element.hide(this._popup);

    },

    // creates the titlebar element for the popup
    _createTitleBar: function () {

        var titleBar = Builder.node('div', {
                className: 'popupTitleBar clearfix'
            }, [
                Builder.node('span', { className: 'left' }, [ this._options.title ]),
                Builder.node('span', { className: 'right' }, [ '' ])
            ]);

        return titleBar;

    },

    // creates the content area element for the popup
    _createContentArea: function () {

        var closeButton = Builder.node('input', {
                type: 'button',
                value: this._options.okText
            });

        var content = Builder.node('div', {
                className: 'popupContentContainer'
            }, [
                Builder.node('div', {
                    className: 'popupContent',
                    style: 'height: ' + this._options.height + 'px'
                }, [ this._options.content ]),
                Builder.node('form', [ closeButton ]),
                Builder.node('div', {
                    className: 'popupResizeHandle'
                })
            ]);

        Event.observe(content.lastChild, 'mousedown', this.eventMouseDown);
        Event.observe(document, 'mouseup', this.eventMouseUp);

        Event.observe(closeButton, 'click', function () {
            this._dragObj.destroy();
            Element.remove(this._popup);
        }.bind(this));

        return content;

    },

    // event handler for the mousedown-event
    _initResize: function () {
        this._startResize(this);
    },

    // event handler for the mouseup-event
    _endResize: function () {
        if (this._doResize) {
            this._stopResize(this);
        } // if
    },

    // starts the resizing
    _startResize: function (self) {

        self._doResize = true;
        self._createGhostRect(self);

        var pos = Position.cumulativeOffset(self._popup);

        self._pos = [pos[0], pos[1]];

        Event.observe(document, 'drag', self.eventDrag);
        Event.observe(document, 'selectstart', self.eventSelectStart);
        Event.observe(document, 'mousemove', self.eventMouseMove);

        self._timer = setInterval(function () {
            self._drawGhostRect(self);
        }.bind(self), 100);

    },

    // stops the resizing
    _stopResize: function (self) {

        clearInterval(self._timer);

        Event.stopObserving(document, 'drag', self.eventDrag);
        Event.stopObserving(document, 'selectstart', self.eventSelectStart);
        Event.stopObserving(document, 'mousemove', self.eventMouseMove);

        self._doResize = false;

        // count the new height for the content area. the height is counted by getting
        // the height of the ghost rectangle and subtracting the height of the titlebar and
        // all the extra paddings and margins from it
        var newHeight = self._ghostRect.offsetHeight - self._titleBar.offsetHeight
                - (self._popup.offsetHeight - self._titleBar.offsetHeight
                - self._contentArea.firstChild.offsetHeight) + 'px';

        var newWidth = self._ghostRect.offsetWidth + 'px';

        self._contentArea.firstChild.style.height = newHeight;
        self._popup.style.width = newWidth;
        self._removeGhostRect(self);

    },

    // creates the ghost rectangle (visible when resizing)
    _createGhostRect: function (self) {

        var popupPos = Position.cumulativeOffset(self._popup);

        self._ghostRect = Builder.node('div', {
                id: self._elId + '_ghost',
                className: 'popupGhostRect',
                style: 'width: ' + self._popup.offsetWidth + 'px; '
                     + 'height: ' + self._popup.offsetHeight + 'px; '
                     + 'left: ' + popupPos[0] + 'px; '
                     + 'top: ' + popupPos[1] + 'px; '
            });

        self._bodyEl.appendChild(self._ghostRect);

    },

    // removes the ghost rectangle
    _removeGhostRect: function (self) {
        Element.remove(self._ghostRect);
    },

    // resizes the ghost rectangle
    _drawGhostRect: function (self) {

        var mouseX  = self._mousePos[0],
            mouseY  = self._mousePos[1],
            dx      = mouseX - self._pos[0],
            dy      = mouseY - self._pos[1];

        if (dx < self._options.minWidth) {
            dx = self._options.minWidth;
        } // if

        if (dy < self._options.minHeight) {
            dy = self._options.minHeight;
        } // if

        if (mouseX != undefined && mouseY != undefined) {
            self._ghostRect.style.width = dx + 'px';
            self._ghostRect.style.height = dy + 'px';
        } // if

    },

    // event handler for the ondrag- and onselectstart -events
    _disableSelection: function () {
        return false;
    },

    // event handler for the onmousemove-event
    _updateMousePos: function (evt) {
        this._mousePos = [Event.pointerX(evt), Event.pointerY(evt)];
    }

};
