dojo.require("dojo.html.*");
dojo.require("dojo.event.*");

function trim(str) {  
    return   str.replace(/(^\s+)|(\s+$)/g,"");  
} 

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);

function createImgSpinner(){
	var spinImg = document.createElement("img");
    spinImg.src="/static/images/spinner_busy.gif";
    dojo.html.setClass(spinImg, 'spinner_busy');
    return spinImg;
}

function SubmitOnce(element, img){
    this.element = element
    this.img = img
    this.onsubmit = function () {
        this.element.parentNode.insertBefore(this.img, this.element);
        this.element.disabled = true;
    }
}

function initSubmitOnce(){
    var elements = dojo.html.getElementsByClass('submit-once');
    if (!elements || elements.length == 0) return;
    var spinnerImg = createImgSpinner();
    for (var i=0; i < elements.length; i++) {
        var func = new SubmitOnce(elements[i], spinnerImg);
        dojo.event.connect(elements[i].form, "onsubmit", func, "onsubmit");
    }
}
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, "onchange", this, "check");
    dojo.event.connect(this.e, "onkeyup", this, "check");
    dojo.event.connect(this.e, "onpaste", 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()
{
    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(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(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()
{
    if (this.e.value == this.example) {
	this.e.value = "";
    }
    this.e.className = this.oldClassName;
}

/*
 * 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');
}

function 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>
    //      ...
    var example_containers = getElementsByClass("example-text-definitions", document, '*');
    if (!example_containers) 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 = trim(definition.substring(pos+1, definition.length));
                element = dojo.byId(id);
                new ExampleText(element, example)
            }
        }
    }
    
    // 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);

// from http://www.dustindiaz.com/getelementsbyclass
function getElementsByClass(searchClass, node, tag)
{
    var classElements = new Array();
    if (node == null)
        node = document;
    if (tag == null)
        tag = '*';
    var els = node.getElementsByTagName(tag);
    var elsLen = els.length;
    var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
    for (i = 0, j = 0; i < elsLen; i++) {
        if ( pattern.test(els[i].className) ) {
            classElements[j] = els[i];
            j++;
        }
    }
    return classElements;
}

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

function toggleSubscribeBox() {
  var box = document.getElementById("subscribe_box");
  if (!box) { return; }
  var button = document.getElementById("rss_link");
  if (!button) { return; }
  box.style.display = box.style.display == "block" ? "none": "block";
  button.style.backgroundColor = button.style.backgroundColor? "": "#FFFF99";
}

/*
 * 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;
    }
    //this function will not work for nesting popup if not given an unique winname for each window
    //var name = winname || 'popup_' + parseInt(Math.random()*1000000000000000);
    var name = winname || 'popup';
    window.popup=window.open(href, name, arg);
    return false;
}

function Popup(element) {
    this.element = element;
    this.width = '800';
    this.height = '650';
    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);

