
/*global ox : true, jQuery, Class, $, _, resizeEvents, getFullImgSrc, activefolder */

/**
 * @namespace
 */
ox = ox !== undefined ? ox : {};

/**
 * @namespace
 */
ox.gui = {
    themePath: getFullImgSrc("")
};

/**
 * Simple JavaScript Inheritance -- John Resig
 * adopted from http://ejohn.org/blog/simple-javascript-inheritance/
 */

(function () {
    
    var constructing = false, fnTest = /xyz/.test(function (xyz) {
        return xyz;
    }) ? /\b_super\b/ : /.*/;
    
    var $ = jQuery;

    // The base Class implementation (does nothing)
    this.Class = function () {
    };

    // Create a new Class that inherits from this class
    this.Class.extend = function (prop) {
        
        var _super = this.prototype;

        // Instantiate a base class (but only create the instance,
        // don't run the "construct" constructor)
        constructing = true;
        var prototype = new this();
        constructing = false;
        
        // allow functions
        if (typeof prop === "function") {
            // create tmp object
            var obj = {};
            // execute function bound to tmp object
            $.proxy(prop, obj)();
            // return obj (which is now changed)
            prop = obj;
        }

        // factory
        var factory = function (name, fn) {
            return function () {
                var tmp = this._super;
                // Add a new ._super() method that is the same method
                // but on the super-class
                this._super = _super[name];
                // The method only need to be bound temporarily, so we
                // remove it when we're done executing
                var ret = fn.apply(this, arguments);
                this._super = tmp;
                return ret;
            };
        };
        
        // Copy the properties over onto the new prototype
        for (var name in prop) {
            // Check if we're overwriting an existing function
            prototype[name] = $.isFunction(prop[name]) && $.isFunction(_super[name]) && fnTest.test(prop[name]) ? factory(name, prop[name]) : prop[name];
        }
        
        // add clone
        prototype.getConstructor = function () {
            return Class;
        };

        // The dummy class constructor
        var Class = function () {
            // All construction is actually done in the "construct" method
            if (!constructing && this.construct) {
                this.construct.apply(this, arguments);
            }
        };

        // Populate our constructed prototype object
        Class.prototype = prototype;
        // Enforce the constructor to be what we expect
        Class.constructor = Class;
        // And make this class extendable
        Class.extend = arguments.callee;

        return Class;
    };
}());

// helper

var $handleContextMenu = function (e) {
    //var e = event || window.event;
    var tag = e.target.tagName;
    var type = e.target.type || "";
    if (tag === "INPUT" && type.search(/^(text|password)$/i) >= 0) {
        return true;
    } else {
        e.preventDefault();
        e.stopPropagation();
        return false;
    }
};

var $handleSelection = function (event) {
    var e = $.event.fix(event || window.event);
    var tag = e.target.tagName;
    var type = e.target.type || "";
    if (tag === "INPUT" && type.search(/^(text|password)$/i) >= 0) {
        return true;
    } else {
        e.preventDefault();
        e.stopPropagation();
        return false;
    }
};

/**
 * Callback wrapper
 */
ox.call = function () {
    var args = $.makeArray(arguments);
    var callback = args.shift();
    if (typeof callback === "function") {
        callback.apply(this, args);
    }
};

/**
 * jQuery plugin
 */
$.fn.intoViewport = function (node) {

    if (!node) {
        return this;
    }
    
    // IE sometimes crashes so...
    try {
        
        var pane = $(node);
        var height = pane.height();
        
        // get visible area
        var y1 = pane.scrollTop();
        var y2 = y1 + height;
        
        // get position
        var pos = this.position();
        var top = pos.top + y1;
        
        // out of visible area?
        if (top < y1) {
            top = top < 50 ? 0 : top;
            pane.scrollTop(top);
        } else if (top > y2) {
            pane.scrollTop(top);
        }
        
    } catch (e) {
        console.error(e);
    }
    
    return this;
};

/**
 * Mousewheel support
 */

(function($) {

    // handler
    var handler = function (event) {
        
        // get event
        var e = event || window.event;
        
        // fix event object
        e = $.event.fix(e);
        
        // set properties
        e.type = "mousewheel";
        e.delta = 0;
        e.deltaSign = 0;
        
        // get delta
        if (e.wheelDelta) {
            e.delta = e.wheelDelta / 120;
        }
        if (e.detail) {
            e.delta = -e.detail / 3;
        }
        
        // signed delta
        if (e.delta !== 0) {
            e.deltaSign = e.delta / Math.abs(e.delta);
        }
        
        // go!
        return $.event.handle.apply(this, [e]);
    };
    
    // event type
    var type = ox.browser.Gecko ? "DOMMouseScroll" : "mousewheel";
    
    // setup/teardown
    $.event.special.mousewheel = {
        setup: function () {
            // add listener
            if (this.addEventListener) {
                // Firefox, Safari, etc.
                this.addEventListener(type, handler, false);
            } else {
                // IE specific
                this.onmousewheel = handler;
            }
        },
        
        teardown: function () {
            // remove listener
            if (this.removeEventListener) {
                // Firefox, Safari, etc.
                this.removeEventListener(type, handler, false);
            } else {
                this.onmousewheel = null;
            }
        }
    };

}(jQuery));

/**
 * IFrame fix
 */

(function ($) {
    
    var tmpl = $("<div/>").css({
        position: "absolute",
        top: "0px",
        left: "0px",
        width: "0px",
        height: "0px",
        opacity: 0.01,
        backgroundColor: "white"
    });
    
    $.fn.overlay = function (flag) {
        
        if (flag === undefined || flag === true) {
            // loop
            this.each(function (i, n) {
                var node = $(n), p = node.parent();
                var w = node.outerWidth(), h = node.outerHeight();
                var pos = node.position();
                // create overlay
                var overlay = tmpl.clone(false).css({
                    top: pos.top + "px",
                    left: pos.left + "px",
                    width: w + "px",
                    height: h + "px"
                });
                // add
                p.append(overlay);
                node.data("overlay", overlay);
            });
        } else {
            // loop
            this.each(function (i, n) {
                var node = $(n), overlay = node.data("overlay");
                if (overlay) {
                    overlay.remove();
                    node.removeData("overlay");
                }
            });
        }
        
        return this;
    };
    
}(jQuery));

$.fixIFrames = (function () {
    
    var overlays = $();
    
    return function (flag) {
        // hide overlays (always)
        overlays.remove();
        overlays = $();
        // show?
        if (flag) {
            // get all visible iframes
            var iframes = $("iframe:visible"), i = 0, $i = iframes.length;
            var iframe, offset, width, height, fix;
            // loop
            for (; i < $i; i++) {
                // get
                iframe = iframes.eq(i);
                // get dimensions
                offset = iframe.offset();
                width = iframe.outerWidth();
                height = iframe.outerHeight();
                // add overlay
                overlays = overlays.add($("<div/>").css({
                    position: "absolute",
                    top: offset.top,
                    left: offset.left,
                    width: width,
                    height: height,
                    zIndex: 5000,
                    backgroundColor: "white",
                    opacity: 0.01
                }).text(" ").appendTo(document.body));
            }
        }
    };
    
}());

$.quickConfig = (function () {
    
    return function (containerSelector, configSelector, linkSelector, textClosed, textOpen) {
        
        var container = $(containerSelector);
        var config = $(configSelector);
        var link = $(linkSelector);
        
        textClosed = textClosed !== undefined ? textClosed : "Quick config"; /*i18n*/
        textOpen = textOpen !== undefined ? textOpen : "Close quick config"; /*i18n*/
        
        if (!config.hasClass("ox-quick-config")) {
            // adjust container
            container.css({
                position: "absolute",
                zIndex: 2
            });
            // remember top position
            container.data("top", parseInt(container.css("top") || 0, 10));
            // adjust config
            config.addClass("ox-quick-config").css({
                position: "absolute",
                zIndex: 1,
                top: (config.css("top") || 0) + "px",
                right: "0px",
                height: "auto",
                left: "0px",
                minHeight: "25px"
            });
            // adjust link
            link
                .css({
                    color: "#00f",
                    textDecoration: "underline",
                    whiteSpace: "nowrap"
                })
                .data("open", false)
                .append(addTranslated(textClosed));
        }
        
        // rebind events
        link.unbind("click")
            .bind("click", function (e) {
                // open
                var top = container.data("top");
                if (link.data("open") === false) {
                    link.data("open", true)
                        .empty().append(addTranslated(textOpen));
                    config.show();
                    var h = Math.max(config.outerHeight(), 25);
                    container.stop().animate({ top: (top + h) + "px" }, 500);
                } else {
                    link.data("open", false)
                        .empty().append(addTranslated(textClosed));
                    container.stop().animate({ top: top + "px" }, 500, function () {
                        config.hide();
                    });
                }
                return false;
            });
    };
}());

$.checkbox = function (id, value, checked, label, fn, data) {
    
    // text node or string/object?
    var text = label.nodeType === 3 ? label : document.createTextNode(label + "");
    
    return $().add(
        $("<input/>", {
            type: "checkbox",
            id: id,
            value: value,
            defaultChecked: !!checked,
            checked: !!checked
        })
        .css("border", "0px none") // for IE
        .bind("change", data !== undefined ? data : {}, fn)
    ).add(
        $("<label/>", { "for": id }).append(text)
    );
};

$.radio = function (name, value, checked, label, fn, data) {
    
    // text node or string/object?
    var text = label.nodeType === 3 ? label : document.createTextNode(label + "");
    
    return $().add(
        $("<input/>", {
            type: "radio",
            name: name,
            id: name + "-" + value,
            value: value,
            defaultChecked: !!checked,
            checked: !!checked
        })
        .css("border", "0px none") // for IE
        .bind("change", data, fn)
    ).add(
        $("<label/>", { "for": name + "-" + value }).append(text)
    );
};

$.button = function (options) {
    
    // options
    var opt = $.extend({
        title: "",
        click: $.noop,
        data: {},
        theme: "bright",
        css: {}
        // other options:
        // tabIndex, id, mousedown
    }, options || {});
    
    // class name
    var className = "ox-button";
    
    if (opt.theme === "dark") {
        // dark theme
        className += " dark";
    }
    
    if (ox.browser.Gecko) {
        // firefox
        className += " firefox";
    } else if (ox.browser.WebKit) {
        // webkit
        className += " webkit";
    }
    
    // create text node
    var text;
    if (opt.title.nodeType === 3) {
        // is text node!
        text = opt.title;
    } else {
        text = addTranslated(opt.title);
    }
    
    // create button
    var button = $("<button/>").addClass(className).append(
        $("<span/>").append(text)
    ).bind(
        "click", opt.data, opt.click
    );
    
    // add id?
    if (opt.id !== undefined) {
        button.attr("id", opt.id);
    }
    
    // add tabindex?
    if (opt.tabIndex !== undefined) {
        button.attr("tabindex", opt.tabIndex);
    }
    
    return button;
};
