dojo.require("dojo.debug");
dojo.require("dojo.string.*");
dojo.require("dojo.string.common");
dojo.require("dojo.html.*");
dojo.require("dojo.event.*");
dojo.require("dojo.widget.Dialog");
dojo.require("dojo.widget.TabContainer");
dojo.require("dojo.widget.LinkPane");
dojo.require("dojo.widget.ContentPane");
dojo.require("dojo.widget.LayoutContainer");
dojo.require("dojo.collections.Dictionary");

/* 
 TODO: refactor confirm to a dojo dialog.
function initDeleteConfirm(){
    var elements = dojo.html.getElementsByClass('delete-confirm');
    if (!elements || elements.length == 0) return;
    for (var i=0; i < elements.length; i++) {
        dojo.event.connect(elements[i], "onclick", function(e){
            if (!confirm("Do you really want to delete this item?")) e.preventDefault();
            });
    }
}
dojo.addOnLoad(initDeleteConfirm); */

/*
 * Popup tools
 *
 * To control the width and height:
     <a href="..." onclick="popup_win(this.href, width, height);">...
 * For shortcut:
     <a href="..." class="popup">...
 */
function popup_win(href, width, height, winname) {
    var arg = 'status=no, resizable=yes, location=no, menubar=no, scrollbars=yes, toolbar=no';
    if (width){
	arg = 'width=' + width + ', ' + arg;
    }
    if (height){
	arg = 'height=' + height + ', ' + arg;
    }
    var name = winname || 'popup_' + parseInt(Math.random()*1000000000000000);
    window.popup=window.open(href, name, arg);
    return false;
}

function Popup(element) {
    this.element = element;
    this.width = '900';
    this.height = '600';
    this.callback = function(e) {
	e.preventDefault();
	popup_win(this.element.href, this.width, this.height);
    }
}

function initPopup() {
    dojo.debug('initPopup');
    var elements = dojo.html.getElementsByClass('popup');
    if (!elements || elements.length == 0) return;
    for (var i=0; i < elements.length; i++) {
        if (elements[i].nodeName.toLowerCase() == 'a') {
	    var callback = new Popup(elements[i]);
	    dojo.event.connect(elements[i], "onclick", callback, "callback");
	}
    }
}
dojo.addOnLoad(initPopup);

/*
 * Dialog shortcut
 */
function showWaitingDialog(msg){
    var dlg = dojo.widget.byId('waiting_dlg');
    if (!dlg) return;
    dojo.debug('showWaitingDialog');
    var msgTag = dojo.byId('waiting_dlg_msg');
    msgTag.innerHTML = msg;
    dlg.show();
}

function hideWaitingDialog(timeout){
    var dlg = dojo.widget.byId('waiting_dlg');
    if (!dlg) return;
    dojo.debug('hideWaitingDialog');
    if (timeout) {
	setTimeout("hideWaitingDialog();", timeout);
    } else {
	dlg.hide();
    }
}

function showMessageDialog(msg) {
    var dlg = dojo.widget.byId('message_dlg');
    if (!dlg) return;
    if (msg) {
	var textTag = dojo.byId('message_dlg_text');
	textTag.innerHTML = msg;
    }
    dlg.show(); 
}

function hideMessageDialog(timeout){
    var dlg = dojo.widget.byId('message_dlg');
    if (!dlg) return;
    dojo.debug('hideMessageDialog');
    if (timeout) {
	setTimeout("hideMessageDialog();", timeout);
    } else {
	dlg.hide();
    }
}

function initMessageDialog() {
    // connect hide button
    var button = dojo.byId('message_dlg_ok');
    if (!button) return;
    dojo.event.connect(button, "onclick", function(e) {
	    hideMessageDialog(); 
	});
    // show message if has content
    var textTag = dojo.byId('message_dlg_text');
    var text = textTag.innerHTML;
    text = text.replace(/[\n\r\s]/g, '');
    if (text) showMessageDialog();
}
dojo.addOnLoad(initMessageDialog);

/*
 * Cancel button shortcut
 */
function cancelCallback(e) {
    window.close();
}

function initCancel() {
    dojo.debug('initCancel');
    var elements = dojo.html.getElementsByClass('cancel');
    if (!elements || elements.length == 0) return;
    for (var i=0; i < elements.length; i++) {
	dojo.event.connect(elements[i], "onclick", cancelCallback);
    }
}
dojo.addOnLoad(initCancel);

/*
 * Submit once form bind
 */
function submitOnceCallback(e) {
    showWaitingDialog(gettext('submiting...'));
}

function initSubmitOnce() {
    dojo.debug('initSubmitOnce');
    var elements = dojo.html.getElementsByClass('submit-once');
    if (!elements || elements.length == 0) return;
    for (var i=0; i < elements.length; i++) {
	dojo.event.connect(elements[i], "onclick", submitOnceCallback);
    }
}
dojo.addOnLoad(initSubmitOnce);

/* Maxlength checker for Textarea
 *
 * Usage: 
 *     new TextareaChecker(textareaElement, maxlength, countdownElement);
 *
 *     textareaElement: the textarea element.
 *     maxlength:  the textarea maxlength.
 *     countdownElement: countdown container. should be any element has a 
 *         textNode inside, like <p> <div> <span>... null means don't need 
 *         a countdown.
 *
 * Shortcut:
 *     <ul id=textarea-maxlength-fixing>
 *        <li>textareaElementId:maxlength:countdownElement<li>
 *        <li>example_id:2000:example_countdown_id<li>
 *     </ul>
 *            
 */ 
function TextareaChecker(e, maxlength, countdown) {
    this.e = e;
    this.maxlength = parseInt(maxlength);
    this.countdown = countdown;
    dojo.event.connect(this.e, "onkeyup", this, "check");
    dojo.event.connect(this.e, "onchange", this, "check");
    dojo.event.connect(this.e, "onblur", this, "check");

    this.check = function() {
	    if (this.e.value.length > this.maxlength) {
		this.e.value = this.e.value.substring(0, this.maxlength);
		this.e.scrollTop = this.e.scrollHeight; // Scrolling to bottom of Textarea
	    }
	    if (this.countdown) {
		this.countdown.innerHTML = this.maxlength - this.e.value.length;
	    }
	}

    this.check();
}

function initTextareaChecker() {
    dojo.debug('initTextareaChecker');
    var checker_container = document.getElementById("textarea-maxlength-fixing");
    if (!checker_container) return;
    var checkers = checker_container.getElementsByTagName('li');
    for (var i=0; i < checkers.length; i++) {
        var checker = checkers[i];
	var data = checker.innerHTML.split(':');
	var element_id = data[0];
	var maxlength = data[1];
	var countdown_element_id = data[2];
	var countdown_element = null;
	var element = document.getElementById(element_id);
	if (countdown_element_id) {
	    countdown_element = document.getElementById(dojo.string.trim(countdown_element_id));
	}
	new TextareaChecker(element, maxlength, countdown_element);
    }
}
dojo.addOnLoad(initTextareaChecker);


/* Emailcount checker for Textarea
 *
 * Usage:
 *     new TextareaEmailChecker(textareaElement, countupElementp);
 *
 *     textareaElement: the textarea element.
 *     maxemailcount:  the textarea max emails count.
 *     countdownElement: countdown container. should be any element has a
 *         textNode inside, like <p> <div> <span>... null means don't need
 *         a countdown.
 *
 * Shortcut:
 *     <ul id=textarea-maxemailcount-fixing>
 *        <li>textareaElementId:maxemailcount:countdownElement<li>
 *        <li>example_id:2000:example_countdown_id<li>
 *     </ul>
 *
 */

function TextareaEmailChecker(e, maxemailcount, countdown) {
    this.e = e;
    this.maxemailcount = parseInt(maxemailcount);
    this.countdown = countdown;
    dojo.event.connect(this.e, "onkeyup", this, "check");
    dojo.event.connect(this.e, "onchange", this, "check");
    dojo.event.connect(this.e, "onclick", this, "check");

    this.check = function() {

        this.count = this.e.value.length - this.e.value.replace(/@/g,"").length

        while (this.count > this.maxemailcount) {
            // Remove to final @ - this must remove the @, avoiding
            // infinite loop
            this.e.value = this.e.value.substring(0,
                                                  this.e.value.lastIndexOf("@")
                                                 )
            // remove back to final comma
            this.e.value = this.e.value.substring(0,
                                                  this.e.value.lastIndexOf(",")
                                                 )

            this.e.scrollTop = this.e.scrollHeight; // Scrolling to bottom
            this.count = this.e.value.length
                         - this.e.value.replace(/@/g,"").length
        }
        if (this.countdown) {
            this.countdown.innerHTML = this.maxemailcount - this.count;
        }
    }

    this.check();
}

function initTextareaEmailChecker()
{
    var checker_container = document.getElementById("textarea-maxemailcount-fixing");
    if (!checker_container) return;
    var checkers = checker_container.getElementsByTagName('li');
    for (var i=0; i < checkers.length; i++) {
        var checker = checkers[i];
        var data = checker.innerHTML.split(':');
        var element_id = data[0];
        var maxemailcount = data[1];
        var countdown_element_id = data[2];
        var countdown_element = null;
        var element = document.getElementById(element_id);
        if (countdown_element_id) {
                countdown_element = document.getElementById(dojo.string.trim(countdown_element_id));
            }
        new TextareaEmailChecker(element, maxemailcount, countdown_element);
    }
}
dojo.addOnLoad(initTextareaEmailChecker);


/* EXAMPLE TEXT IN INPUT FIELDS
 * Usage:
 *
 *   <INPUT ... example="Some example text" />
 *   ...
 *   new ExampleText(dojo.byId("myNode"));
 *
 * Registers example texts for all elements with class "show-example-text"
 * of type "input".  An example text is a text shown with styling of class
 * "example" (typically greyed out) whenever the input field is empty.
 *
 * The below implementation gets the example text from one of two places:
 * 1) If the input element has an attribute called "example", that is used
 * 2) If not, it'll look for an element with id "text-<section>-<id>"
 *    where `id` is the id of the input field, and `section` is found by
 *    looking at the class attribute of the element with id "body"; this is
 *    hackish, but fits how we currently do the CW site.
 *
 * TODO:
 * - The "example" style doesn't seem to get applied to Firefox until
 *   after you click in the field.  It works in Safari, though.
 * - We should combine the many js files into one for faster downloading
 * - It would be great if we could store the example text in some
 *   CSS property of the input field itself, but it seems like the "content"
 *   property is only available for the :before and :after pseudo-elements.
 *
 * -----------
 * <ul class="example-text-definitions">
 *   <li>id_title_en: Blasadjklf kalsdf</li>
 *   ...
 * </ul>
 * 
 * 1. collect example text definitions, result is an assoc array of
 *    field elements and their example texts, and the associated form element
 * 2. install
 *    - the example texts on the fields in the given form (using the specified class)
 *    - connect a function to submit buttons that removes example texts upon submit
 *
 * TODO:
 * - refactor dataFilter and initExampleTexts to use same function to retrieve example texts
 */

/* Wrapper for elements to set/clear example text */
function ExampleText(e, str) {
    this.e = e;
    if (str) this.example = str;
    /*
    if (this.e.example) {
        this.example = this.e.example;
    } else if (typeof(str) != null && typeof(str) != undefined) {
        this.example = str;
    } else {
        var section = dojo.byId("page").className;
        this.example = dojo.byId("text-"+ section +"-"+ this.e.id).innerHTML;
    }
    */
    this.oldClassName = this.e.className;
    dojo.event.connect(this.e, "onblur", this, "set");
    dojo.event.connect(this.e, "onfocus", this, "clear"); 
    this.set();
}

ExampleText.prototype.set = function() {
    if (this.e.value == "") {
	this.e.value = this.example;
	this.e.className = "example " + this.oldClassName;
    }
}

ExampleText.prototype.clear = function() {
    var dos2unix = function (str) { 
        return str.replace(new RegExp("\\r", "g"), '');
    };
    s1 = dos2unix(this.e.value);
    s2 = dos2unix(this.example);
    if (s1 == s2) {
	this.e.value = "";
    }
    this.e.className = this.oldClassName;
}

function initExampleTexts() {
    dojo.debug('initExampleTexts');
    // option 2: create a list with class 'example-text-definitions' that contains
    // list items of the form:
    //      <li>id_title_en: Example text for title_en field</li>
    //      ...
    // Notice that this method will have a bug in IE, the help text will lose all breakline
    // (IE innerhtml will filter all breakline out).
    //
    // option 3: use a global dict "example_dict" to store help text
    //      example_dict = new dojo.collections.Dictionary();
    //      example_dict.add('id_other_ingredients', 'multi-line help text here\nsecond line');

    var example_containers = dojo.html.getElementsByClass("example-text-definitions");
    example_dict_exist = typeof example_dict != 'undefined';
    if (!example_containers && !example_dict_exist) return;
    for (var i=0; i < example_containers.length; i++) {
        examples = example_containers[i].childNodes;
        for (var j=0; j < examples.length; j++) {
            if (examples[j].nodeName == 'LI') {
                var definition = examples[j].innerHTML;
                pos = definition.indexOf(':');
                id = definition.substring(0, pos);
                example = dojo.string.trim(definition.substring(pos+1, definition.length));
                element = dojo.byId(id);
                new ExampleText(element, example);
            }
        }
    }

    if (example_dict_exist) {
        example_dict.forEach(function(item){ new ExampleText(dojo.byId(item.key), item.value); });
    }
    
    // install a hook on all forms to remove sample data upon form submission
    var forms = document.getElementsByTagName("form");
    for (var i=0; i < forms.length; i++) {
        dojo.event.connect(forms[i], "onsubmit", function(e) {
            //e.preventDefault();
            dataFilter();
        });
    }
}
dojo.addOnLoad(initExampleTexts);

/*
 * Clear help-text when submit
 */
function dataFilter() {
    dojo.debug('dataFilter');
    var element_ = dojo.html.getElementsByClass("example-text-definitions");
    if (!element_ || element_.length == 0) return;
    elements_ = element_[0].childNodes;
    for (var i=0; i < elements_.length; i++) {
        if (elements_[i].nodeName == 'LI') {
            var definitions = elements_[i].innerHTML;
            posi = definitions.indexOf(':');
            id = definitions.substring(0, posi);
            example = dojo.string.trim(definitions.substring(posi+1, definitions.length));
            value = dojo.byId(id).value;
            if (value == example) {
                dojo.byId(id).value = "";
            }
        }
    }
}

/*
 * Add example text for dojo combo widget.
 * Usage: new ExampleTextForDojoComboWidget('widgetId', 'ExampleText');
 */
function ExampleTextForDojoComboWidget(widgetId, exampleText) {
    /* hacky code to set example text for dojo combo widget
      1. dojo combo widget textInputNode has no id, we have to build ExampleText directly.
      2. dojo combo widget will clean unvalid input when textInputNode blur(delay 500ms).
      we insert a fade data ("", example_text) to the option list to cheat dojo. 
     */
    // init
    this.widgetId = widgetId;
    this.exampleText = exampleText;
    this.widget = dojo.widget.byId(widgetId);
    var textInputNode = this.widget.textInputNode;

    // fade example_text as a valid option value.
    this.insertFadeData = function() {
	var td = document.createElement("div");
	td.appendChild(document.createTextNode(this.exampleText));
	td.setAttribute("resultName", this.exampleText);
	td.setAttribute("resultValue", ''); //empty value
        var even = true;
	td.className = "dojoComboBoxItem "+((even) ? "dojoComboBoxItemEven" : "dojoComboBoxItemOdd"); 
	this.widget.optionsListNode.appendChild(td);
    }
    dojo.event.connect(textInputNode, "onblur", this, 'insertFadeData');

    // remove fade example_text from options.
    this.removeFadeData = function() {
        options = this.widget.optionsListNode.childNodes;
        for (var i=0; i<options.length; i++) {
	    if (options[i].innerHTML == this.exampleText) {
		this.widget.optionsListNode.removeChild(options[i]);
		break;
	    }
        }
    }
    dojo.event.connect(textInputNode, "onfocus", this, "removeFadeData");

    new ExampleText(textInputNode, this.exampleText); // set example text

    this.resetExampleText = function() {
        // this only happen when the inputfield blur with unvalidable value.
	// we need resetExample after dojo cleans value.
        if (!this.widget._hasFocus && this.widget.textInputNode.value != this.exampleText) {
	    this.widget.textInputNode.onblur();
	}
    }
    dojo.event.connect(this.widget, "checkBlurred", this, 'resetExampleText');
}


