/*
* Qusion UI Popover 2.0
*
* Copyright 2011, AUTHORS.txt (http://qusion.net/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://qusion.net/license
*
* http://docs.qusion.net/ui/popover
*
* Depends:
*	jquery.ui.widget.js
*	jquery.ui.position.js
*	jquery.ui.menu.js (optional)
*/

(function ($) {

    $.widget("qusion.popover", {
        options: {
            enableDataAttributes: true,
            closeOnEscape: true,
            closeOnSelect: true,
            height: 'auto',
            width: 'auto',
            minWidth: '150px',
            minHeight: 'auto',
            maxWidth: 'auto',
            maxHeight: 'auto',
            openEvent: 'click',
            closeEvent: 'click',
            openDelay: 0,
            closeDelay: 0,
            trigger: null,
            closeTrigger: null,
            closeOther: true,
            closeChildren: true,
            menu: true,
            position: {
                my: 'left top',
                at: 'left bottom',
                collision: "flipfit flipfit",
                offset: "0 0"
            }
        },
        _create: function() {
            var self = this;
            // default is closed
            self.isOpen = false;
            //console.log(this.options.position);
            // parent container
            //(self.element.parents(':qusion-selectbox').length > 0)
            //    ? self.container = self.element.parents(':qusion-selectbox').get(0)
            self.container = document;

            // basic data for our element
            self.element
                .uniqueId()
                .attr({
                    role: "popover"
                })
                .addClass('q-popover')
                .css({
                    'overflow-y': 'auto',
                    minWidth: self.options.minWidth,
                    minHeight: self.options.minHeight,
                    maxWidth: self.options.maxWidth,
                    maxHeight: self.options.maxHeight,
                    height: self.options.height != 'auto' ? self.options.height : null,
                    width: self.options.width != 'auto' ? self.options.width : null
                })
                .on(self.options.openEvent, function(e) {
                    e.stopPropagation();
                });

            // trigger
            self.trigger = self.options.trigger ? $(self.options.trigger) : self.element.prev();
            self.trigger
                .on(self.options.openEvent, function(e) {
                    setTimeout(function() {
                        if (self.isOpen)
                            self.close(e);
                        else
                            self.open(e);
                    }, self.options.openDelay);
                });

            // menu
            if (self.options.menu === true) {
                self.menu = self.element.find('ul')
                    .menu({
                        select: function(event, ui) {
                            self._trigger('select', event, ui);
                            if (self.options.closeOnSelect === true)
                                self.close(event);
                        }
                    });
            }
            // initially hide element
            self.element.hide();

            // events
            this._on(this.element, {
                keydown: function(event) {
                    var keyCode = $.ui.keyCode;
                    if (event.keyCode == keyCode.ESCAPE)
                        self.close();
                }
            });


        },
        open: function(e, position) {
            var self = this,
                trigger = self.trigger || $(e.currentTarget);

            // ensure there is a trigger
            //if (!trigger)
            //    trigger = self.trigger;

            // we don't want to propagate event to parent
            //e.stopPropagation();

            // we don't want to open if already open
            if (self.isOpen !== false) return;

            position = position || { };
            position.of = trigger;
            position = $.extend({ }, self.options.position, position);

            // set positions
            self.element
                .css({ 'z-index': 3, position: 'absolute' })
                .show()
                .position(position);

            trigger.addClass('active');

            // when popover opens we want to be closed on body or some other parent click
            $(self.container)
                .on('click', function (ev) {

                    var element = $(ev.target);

                    var skip = (function () {
                        var skip = false;
                        element.parents().add(element).each(function () {
                            if ($(this).is('.colorPicker-palette')
                             || $(this).data('datepicker')
                            ) {
                                skip = true;
                                return false;
                            }
                        });
                        return skip;
                    })();

                    if (skip) {
                        return true;
                    }

                    ev.stopPropagation();
                    if (ev.which === 1) {
                        self.close(ev);
                    }
                });

            $(self.element).find('input').first().focus();

            // TODO: hack to not close pane when datepicker closes
            /*
            $(self.element).find(":input").each(function () {
                var datepicker = $(this).data('datepicker');

                if (datepicker) {
                    datepicker.dpDiv.on('click', function (e) {
                        e.stopPropagation();
                    });
                }
            });
            */

            /*
            $(self.element).find('.hasDatepicker').each(function() {
                var dpdata = $(this).data('datepicker');
                if (dpdata)
                    dpdata.dpDiv.on('click', function(ev) {
                        ev.stopPropagation();
                    });
            });
            */


            if (self.options.closeOther === true)
                self.element
                    .find(':qusion-popover')
                    .not(this)
                    .popover('close', e);

            // set isOpen to true
            self.isOpen = true;
            // trigger 'open' event for external event handlers
            self._trigger("open", e);
        },
        close: function(e) {
            var self = this;
            if (self.isOpen !== true) return;

            self.element.hide();
            self.isOpen = false;

            self.trigger.removeClass('active');

            if (self.options.closeChildren === true)
                self.element
                    .find(':qusion-popover')
                    .popover('close', e);

            // trigger 'close' event for external event handlers
            self._trigger("close", e);
        },
        _setOption: function(key, value) {
            this._super(key, value);
            switch (key) {
            case "disabled":
                if (value) {
                    this.element.addClass("ui-disabled");
                    if (self.trigger)
                        self.trigger.addClass("ui-disabled");
                } else {
                    this.element.removeClass("ui-disabled");
                    if (self.trigger)
                        self.trigger.removeClass("ui-disabled");
                }
                break;
            case "height":
            case "width":
            case "minWidth":
            case "minHeight":
            case "maxWidth":
            case "maxHeight":
                this.element.css({ key: value });
                break;
            }

        }
    });
})(jQuery);