/*
 * 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) {
	return popup_win(this.element.href, this.width, this.height);
    }
}

function initPopup() {
    var elements = $('.popup');
    $('.popup').each(function(){
        if (this.nodeName.toLowerCase() == 'a') {
            $(this).click(function(){ return new Popup(this).callback(); });
	}
    });
}

/*
 * Dialog shortcut
 */
function showUnderlay(){
  $('#dialog_underlay').show();
}

function hideUnderlay(){
  $('#dialog_underlay').hide();
}

function showWaitingDialog(msg){
  if (msg) { $('#waiting_dlg_msg').html(msg); }
  $.trim($('#waiting_dlg_msg').html()) ? 
    $.fn.colorbox({width:"50%", inline:true, open:true, href:"#waiting_dlg_msg"}):
    null;
}

function hideWaitingDialog(timeout){
  if (timeout) {
    setTimeout("hideWaitingDialog();", timeout);
  } else {
    if ($('#cboxLoadedContent #waiting_dlg_msg')[0]) { $.fn.colorbox.close(); };
  }
}

function showMessageDialog(msg) {
  if (msg) { $('#message_dlg_text').html(msg); }
  $.trim($('#message_dlg_text').html()) ? 
    $.fn.colorbox({width:"50%", inline:true, open:true, href:"#message_dlg_text"}):
    null;
}

function hideMessageDialog(timeout){
  if (timeout) {
    setTimeout("hideMessageDialog();", timeout);
  } else {
    if ($('#cboxLoadedContent #message_dlg_text')[0]) { $.fn.colorbox.close(); };
  }
}

function initMessageDialog() {
  if ($.trim($("#message_dlg_text").html())) { showMessageDialog(); }
}

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

function initCancel() {
  $('.cancel').click(function(){ cancelCallback(); });
}

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

function initSubmitOnce() {
  $('.submit-once').click(function(){ submitOnceCallback(); });
}

/* 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)[0];
    this.maxlength = parseInt(maxlength);
    this.countdown = $(countdown);

    e.bind('onkeyup', function(){ this.check(); });
    e.bind('onchange', function(){ this.check(); });
    e.bind('onblur', function(){ 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.html(this.maxlength - this.e.value.length);
	    }
	}

    this.check();
}

function initTextareaChecker() {
  $('#textarea-maxlength-fixing li').each(function(){
    var checker = $(this);
    var data = checker.html().split(':');
    var element_id = data[0];
    var maxlength = data[1];
    var countdown_element_id = data[2];
    var countdown_element = null;
    var element = $('#'+element_id);
    if (countdown_element_id) {
        countdown_element = $('#'+$.trim(countdown_element_id));
    }
    new TextareaChecker(element, maxlength, countdown_element);
  });
}


/* 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)[0];
    this.maxemailcount = parseInt(maxemailcount);
    this.countdown = countdown;
    e.bind('onkeyup', function(){ this.check(); });
    e.bind('onchange', function(){ this.check(); });
    e.bind('onclick', function(){ 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.html(this.maxemailcount - this.count);
        }
    }

    this.check();
}

function initTextareaEmailChecker()
{
  $('#textarea-maxemailcount-fixing li').each(function(){
    var checker = $(this);
    var data = checker.html().split(':');
    var element_id = data[0];
    var maxemailcount = data[1];
    var countdown_element_id = data[2];
    var countdown_element = null;
    var element = $('#'+element_id);
    if (countdown_element_id) {
            countdown_element = document.getElementById(dojo.string.trim(countdown_element_id));
        }
    new TextareaEmailChecker(element, maxemailcount, countdown_element);
  });
}

/* 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)[0];
    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;
    e.bind('onblur', function(){ this.set(); }); 
    e.bind('onfocus', function(){ 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() {
  // 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');

  example_dict_exist = typeof example_dict != 'undefined';
  if (!$('.example-text-definitions') && !example_dict_exist) return;
  $('.example-text-definitions').children('li').each(function(){
      var definition = $(this).html();
      pos = definition.indexOf(':');
      id = definition.substring(0,pos);
      example = $.trim(definition.substring(pos+1, definition.length));
      element = $('#'+id);
      new ExampleText(element, example);
  });

  if (example_dict_exist) {
    for (key in example_dict) {
      new ExampleText($('#'+key), example_dict[key]);
    }
  }

  // install a hook on all forms to remove sample data upon form submission
  var forms = document.getElementsByTagName("form");
  $(forms).each(function(){
    $(this).bind('onsubmit', function(){
      dataFilter();
      return true;
    });
  });
}

/*
 * Clear help-text when submit
 */
function dataFilter() {
  $('.example-text-definitions li').each(function(){
    var definitions = $(this).html();
    posi = definitions.indexOf(':');
    id = definitions.substring(0, posi);
    example = $.trim(definitions.substring(posi+1, definitions.length));
    value = $('#'+id).val();
    if (value == example){
      $('#'+id).val('');
    }
  });
}

$(function(){
  initPopup();
  initMessageDialog();
  initCancel();
  initTextareaChecker();
  initTextareaEmailChecker();
  initExampleTexts();
});
