/**
 * 
 * All content on this website (including text, images, source
 * code and any other original works), unless otherwise noted,
 * is licensed under a Creative Commons License.
 * 
 * http://creativecommons.org/licenses/by-nc-sa/2.5/
 * 
 * Copyright (C) 2004-2009 Open-Xchange, Inc.
 * Mail: info@open-xchange.com 
 * 
 * @author Matthias Biggeleben <matthias.biggeleben@open-xchange.com>
 * @author Stefan Preuss <stefan.preuss@open-xchange.com>
 * @ignore
 */

// DEVELOPMENT IN PROGRESS // SUBJECT TO PERMANENT CHANGE!

ox.gui.Button = ox.gui.Widget.extend({
/** @lends ox.gui.Button.prototype */
    
    getClass: function() { return "ox.gui.Button"; },
    
    /** 
     * A button widget.
     * @constructs
     * @extends ox.gui.Widget
     * @param {String} text The text of the button.
     * @param {Function} clickListener The default callback ("dom:click").
     */
    construct: function(text, clickListener) {
    
        this.clonable = true;
        
        // call super class constructor (inherit from Container)
        this._super(this.autoId(0, "button"));
        this.text = text;
        this.textNode = $("<span/>");
        
        // enable & handle
        this.enableI18n();
        this.i18nHandler();
        
        // dom:click
        if (clickListener) {
            this.addListener("dom:click", clickListener);
        }
    },
    
    i18nHandler: function() {
        this.textNode.attr("title", expectI18n(this.text))
                     .text(expectI18n(this.text));
    },
    
    paint: function() {

        $(this.dom.node).append($("<div/>").addClass("fakeButton background-color-default cursorPointer logoutground").
                append($("<div/>").addClass("fakeButtonBottom").
                        append($("<div/>").addClass("fakeButtonLeft").
                                append($("<div/>").addClass("fakeButtonRight").
                                        append($("<div/>").addClass("fakeButtonTopLeft").
                                                append($("<div/>").addClass("fakeButtonTopRight").
                                                        append($("<div/>").addClass("fakeButtonBottomLeft").
                                                                append($("<div/>").addClass("fakeButtonBottomRight").append(this.textNode)))
                                                )
                                        )
                                )
                        )
                )                
        );
        
        if (!this.isEnabled()) {
            this.paintDisabled();
        }
    },
    
    paintVisible: function() {
        this.dom.node.style.display = "inline";
    },
    
    paintEnabled: function() {
        if (this.dom.node.firstChild) {
            this.dom.node.firstChild.disabled = false;
        }
    },

    paintDisabled: function() {
        if (this.dom.node.firstChild) {
            this.dom.node.firstChild.disabled = true;
        }
    },

    /**
     * Sets the global event to fire when the button is clicked.
     * @param {String} eventName The name of the event.
     */
    setEvent: function(eventName) {
        this.addListener("dom:click", function() {
            this.triggerEvent(eventName);
        });
    },

    /**
     * Sets the widget event to fire when the button is clicked.
     * @param {String} eventName The name of the event.
     */
    setWidgetEvent: function(eventName, eventSource) {
        this.addListener("dom:click", function() {
            var source = eventSource || this;
            source.triggerWidgetEvent(eventName);
        });
    }
});


ox.gui.SearchField = ox.gui.Widget.extend(function () {
    
    var searchImg, searchMenuImg, cancelImg, textChanged;
        
    this.getClass = function() {
        return "ox.gui.SearchField"; 
    };
        
    this.construct = function(id, options) {
        
        // call super class constructor (inherit from Container)
        this._super(this.autoId(id, "ox.gui.SearchField"));
        
        var Self = this;
        
        this.options = $.extend({
            defaultText: _("Please enter your search"),
            width: 228
        }, options);
        
        this.firstPaint = true;
        
        this.p = {};
        
        this.p.input = $("<input/>").attr({ type: "text", value: "Please enter your search", role: "textbox" }).
        css({ border: "none", color: "silver", width: this.options.width + "px", background: "transparent",
            outline: "none", display: "inline-block", height: "17px", marginLeft: "3px",
            marginTop: "0px" }).
        bind("keyup focusin focusout", this.options, function (event) {
            if (event.type == "focusin" && !Self.p.textChanged) {
                $(this).attr({ value: "" }).css({ color: "black" });
            } else if (event.type == "focusout" && $(this).attr("value") == "") {
                $(this).attr({ value: expectI18n(event.data.defaultText) }).css({ color: "silver" });
                $(Self.p.cancelImg).css({ visibility: "hidden" });
            } else {
                switch(event.which) {
                    case 27:
                        Self.p.textChanged = false;
                        $(this).attr("value", "");
                        $(this).blur();
                        break;
                    case 13:
                        Self.trigger("widget:search", { value: $(this).attr("value") });
                    default:
                        Self.p.textChanged = true;
                        $(Self.p.cancelImg).css({ visibility: "visible" });
                }
            }
        });
        
        this.p.input.bind("mousedown", function(event) {
            // stop propagation, required for panel implementation
            event.stopPropagation();
        });
        
        this.p.searchMenuImg = $("<div/>").
        css({ "float": "left", height: "1.6em", width: "16px", verticalAlign: "middle", textAlign: "center", backgroundColor: "#65769B" }).
        append(
                $("<img/>").attr({ src: getFullImgSrc("img/arrows/arrow_gray_down.gif"), align: "absmiddle" })
        );
        
        this.p.searchImg = $("<img/>").
        attr({ src: getFullImgSrc("icons/16/search.png"), align: "absmiddle" }).
        css({ cursor: "pointer", "float": "right", marginTop: "2px", marginRight: "3px", marginLeft: "3px" }).
        click(function() {
            // fire only search if something really changed
            if (Self.p.textChanged && Self.p.input.attr("value") != "") {
                Self.trigger("widget:search", { value: Self.p.input.attr("value") });
            }
            return false;
        });
        
        this.searchMenu = new PulldownMenu(this.p.searchMenuImg[0]);
        
        this.searchMenu.setFields = function(fields, names, checked) {
            this.removeAllItems();
            this.onChange = emptyFunction;
            if (fields && fields.length) {
                this.checked = checked;
                for (var i = 0; i < fields.length; i++) {
                    var item = new MenuItem(names[i], function() {
                        Self.searchMenu.checked[this.searchField] = this.getChecked();
                        Self.searchMenu.onChange();
                    });
                    item.searchField = fields[i];
                    item.setChecked(checked[fields[i]]);
                    Self.searchMenu.addItem(item);
                }
                Self.p.searchMenuImg.css({ display: "" });
            } else {
                Self.p.searchMenuImg.css({ display: "none" });
            }
        }
        
        this.p.cancelImg = $("<img/>").attr({ src: getFullImgSrc("img/x.png"), align: "absmiddle" }).
        css({ marginTop: "2px", marginRight: "5px", cursor: "pointer", visibility: "hidden", "float": "right" }).
        bind("click", this.options, function (event) {
            //$(Self.p.input).attr({ value: expectI18n(event.data.defaultText) }).css({ color: "silver" });
            $(this).css({ visibility: "hidden" });
            $(Self.p.input).attr("value", "");
            $(Self.p.input).blur();
            Self.p.textChanged = false;
            // todo: move to own trigger event  
            triggerEvent('OX_Delete_Search');
        });
    };

    this.paint = function() {
        
        var Self = this;
        
        // paint it once only
        // otherwise, you need to call "empty" (as before) which, however, kills lots of event handlers
        if (this.firstPaint) {
            $(this.dom.node).addClass("border-color-design").
            css({
                backgroundColor: "white",
                border: "1px inset silver", 
                MozBorderRadius: "5px",
                WebkitBorderRadius: "5px",
                lineHeight: "1.5em"
            }).append(
                $("<div/>")
                .css({ overflow: "hidden", height: "18px", whiteSpace: "nowrap" })
                .append(this.p.searchMenuImg)
                .append(this.p.searchImg)
                .append(this.p.cancelImg)
                .append(this.p.input)
            );
            if (this.options.disabled) {
                this.disable();
            }
            this.firstPaint = false;
        }
        
        // adjust width
        this.p.input.css("width", this.options.width + "px");
    };
    
    this.disable = function() {
        this._super();
        this.options.disabled = true;
        if (this.p.input !== undefined) {
            this.p.input.attr({ disabled: "disable", value: "" });
            this.p.searchImg.css({ cursor: "default", opacity: ".2" });
            $(this.dom.node).css({ backgroundColor: "transparent" });
        }
        return this;
    };
    
    this.enable = function() {
        this._super();
        if (this.p.input !== undefined) {
        	$(this.dom.node).css({ backgroundColor: "white" });
        	this.p.searchImg.css({ cursor: "pointer", opacity: "" });  
            this.p.input.attr({ disabled: null, value: expectI18n(this.options.defaultText) }).css({ color: "silver" });
            this.p.cancelImg.css({ visibility: "hidden" });
            this.p.textChanged = false;
        }
        return this;
    };
    
    this.getValue = function() {
        return this.p.input.value();
    };
    
    this.setValue = function(value) {
        this.p.input.focus();
        this.p.input.value(value);
    };
});

ox.gui.Bar = ox.gui.Widget.extend({
	    
	    getClass: function() { return "ox.gui.Bar"; },
	    
	    /**
	     * Constructor
	     */
	    construct: function(options) {
	        this._super(this.autoId(0, "bar")); 
	        
	        // default options
	        this.options = $.extend({
	            max: 100,
	            width: "100%",
	            height: "10px",
	            showText: true,
	            textFormat: 'percentage',
	            title: "%1$s / %2$s",
	            boxBGImage: getFullImgSrc('img/pg_bg.png'),
	            barImage: {
	        		0: getFullImgSrc('img/pg_green.png'),
	        		75: getFullImgSrc('img/pg_orange.png'),
	        		90: getFullImgSrc('img/pg_red.png')
	        	}
	        }, options);
	        
	        this.barNode = $("<div>").
	        css({ background: 'url(' + this.options.barImage["0"] + ')', 
	        	position: "absolute", width: 0, left: 0, top: 0, bottom: 0 });
	        this.barText = $("<span/>").css({ position: "relative", lineHeight: "1em", fontSize: "9pt", margin: "0px 5px" });
	    },
	    
	    paint: function() {
	    	$(this.dom.node).empty();
	    	
	    	$(this.dom.node).
	    	append($("<table/>").attr({ width: "100%", cellSpacing: "0", cellPadding: "0" }).
	    	        append($("<tr/>").
	    	                append($("<td/>").css({ width: this.options.width }).
	    	                        append(
	    	                                $("<div/>").
	    	                                css({ background: 'url(' + this.options.boxBGImage + ')', 
	    	                                    height: this.options.height,
	    	                                    border: "1px solid gray", position: "relative",
	    	                                    margin: "0px 5px" }).
	    	                                append(this.barNode)
	    	                        )
	                        ).append($("<td/>").css({ whiteSpace: "nowrap" }).
	                                append(this.barText)
                            )
                    )
            );
	    },
	    
	    /**
	     * Sets the max. value used for drawing the bar
	     * @param {Integer}
	     */
	    setMax: function(max) {
	    	this.options.max = max;
	    },
	    
	    /**
	     * Updates the progress by the given value
	     * @param {Integer} Used value
	     */
	    progress: function(used) {	        
	    	// calculate position
	    	var percent = Math.round((used / this.options.max) * 100);
	    	this.barNode.css("width", percent + "%");
	    	
	    	// default bar image
	    	var img = this.options.barImage["0"];
	    	// iterate through given steps and grep image
	    	for (var i in this.options.barImage) {
	    		if (i > percent) break;
	    		img = this.options.barImage[i];
	    	}

	    	// should no text be shown?
	    	this.barText.css({ display: this.options.showText ? "" : "none" });
	    	
	    	// sets the text shown on the right
	    	if (ox.util.isFunction(this.options.textFormat)) {
	    	    this.barText.text(this.options.textFormat(used, this.options.max));
	    	} else if (this.options.textFormat === "percentage") {
	    	    this.barText.text(percent + "%");
	    	} else {
	    	    this.barText.text(used + " / " + this.options.max);
	    	}
	    	
	    	// sets the title
	    	if (ox.util.isFunction(this.options.title)) {
	    	    $(this.dom.node).attr("title", this.options.title(used, this.options.max));
	    	} else {
	    	    $(this.dom.node).attr("title", format(this.options.title, used, this.options.max));
	    	}
	    	
	    	// re-set bar image
	    	this.barNode.css("background", 'url(' + img + ')');
	    }
});