String.prototype.escapeHTML = function () {                                       
    return(                                                                 
           this.replace(/&/g,'&amp;').                                         
           replace(/>/g,'&gt;').                                           
           replace(/</g,'&lt;').                                           
           replace(/"/g,'&quot;')                                         
        );                                                                     
    };
// "))} // emacs indent fix.
function toggle_disable(id, disable) {
    $(id).disabled = disable;
}

function set_default_message(id, message) {
  obj = $(id);
  if(obj.value=='') {
    obj.value=message;
    obj.setStyle({color:'#999'});

  }
}

function clear_default_message(id, message) {
  obj = $(id);
  if (obj.value == message) {
    obj.value = '';
    obj.setStyle({color:'#333'});  
  }
}

function show_relative_name(prefix_id, container_id) {
  if ($(container_id + prefix_id + 'relative_id').value == "0") {
	  $(container_id).getElementsBySelector('.rel_name')[0].show();
  }
  else {
	  $(container_id).getElementsBySelector('.rel_name')[0].hide();
  }
  return false;
}

function handle_conditions(parent_div, sub_div, handle_tags) {
	toggle_expander(sub_div,'');
	toggle_checkbox_false(parent_div, sub_div, handle_tags);
}

function toggle_checkbox_false(parent_div, sub_div, handle_tags) { 
  if ($(parent_div).checked == false) {
    var f = $$('div#'+sub_div+' input');
    for(var i=0; i<f.length; i++){
      f[i].checked = false;
      if (handle_tags) {
        delete_tag(1,f[i].value);
      }
    }
  }
  return false;
}

function toggle_expander(section,names) {	
	if ($(section).style.display == "none") {
        	$(section).show();
      if ($(section+'_arrow')) {
		  $(section+'_arrow').className = 'expand_up';
		  if (names.length > 0) {
	   		$(section+'_arrow').innerHTML = names[1];
		  }
		}
	}
	else {
	   $(section).hide();
	   if ($(section+'_arrow')) {
  		  $(section+'_arrow').className = 'expand_down';
		  if (names.length > 0) {
	  		  $(section+'_arrow').innerHTML = names[0];
		  }
	   }
	}
}



function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
	location.reload(true);
}

cookie_name = 'Preferences';

function delete_cookie ()
{
  var cookie_date = new Date ( );  // current date & time
  cookie_date.setTime ( cookie_date.getTime() - 1 );
  document.cookie = cookie_name += "=; expires=" + cookie_date.toGMTString();
  location.reload(true);
}


function hide () {
	document.getElementById('cover').style.display = "none";
	document.getElementById('loginpopup').style.display = "none";
	document.body.style.overflow = "auto";
}

function show () {
	document.getElementById('cover').style.display = "block";
	document.getElementById('loginpopup').style.display = "block";
	document.body.style.overflow = "hidden";

}


var current_lightbox;

function validate_email(email){
  var emailRegEx = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
  return email.match(emailRegEx);
}

function emailThisPage(id) {
	Dialog.info($(id).innerHTML, {className: "alphacube",  width:300, id: "emailThis", recenterAuto: false, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}, onShow: initEvent});
}

	
function contactUs(id) {
	Dialog.info($(id).innerHTML, {className: "alphacube",  width:350, id: "contactUs", recenterAuto: false, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}, onShow: initEvent});
}
 
 
function initEvent() {
       Event.observe("overlay_modal", "click", function() { Windows.closeAllModalWindows(); });
}


/* Fills the hidden tag field from the javascript 
 * tags array. This function is used after a tag
 * is added or removed from the tags array.
*/
function update_tag_fields(uid) {
	tag_sub_element(uid, 'hidden_tag_list').value = tags[uid].join(",");
	tag_sub_element(uid, 'tag_list').innerHTML = tags[uid].collect ( function(t) {
		return "<div class='tag'><span>" + t.escapeHTML() + "</span><a title='delete tag' onclick='delete_tag(" + uid + ", \"" + t.escapeHTML() + "\")'></a></div>";
	}
	).join(" ");
}
function tag_sub_element(uid, element_class) {
	return $$('.tag_controls_' + uid + ' .' + element_class)[0];
}

function add_tag(uid, tag_name) {
	// trim spaces
	tag_name = tag_name.replace(/^\s+|\s+$/g,"");
	// lower case tag_list names to compare new tag names
	tag_names = tags[1].map( function(name) { return name.toLowerCase(); } );
	if (tag_name.length > 0 && !tag_names.include(tag_name.toLowerCase())) {
		/* add the tag to the tags array and let
		 * update_tag_fields do its magic
		*/
		tags[uid].push(tag_name);
		update_tag_fields(uid);
	}
	return false;
}

function toggle_tag_from_checkbox(uid) {
	tag_name_element = tag_sub_element(uid, 'chk_bx');
	tag_name = tag_name_element.value;
	if (tag_name_element.checked == true) {
		add_tag(1,tag_name);
   } else {
	   delete_tag(1,tag_name);
   }
	return false;
}

function add_tag_from_input(uid) {
	/* check if the tag field is empty or if it's already been
	 * added
	*/
	tag_name_element = tag_sub_element(uid, 'tag_name');
	tag_name = tag_name_element.value;
	add_tag(uid, tag_name);
	tag_name_element.value = '';
	return false;
}

function delete_tag(uid, deleted_tag) {
	// remove from tags array and update tag fields
	tags[uid] = tags[uid].without(deleted_tag);
	update_tag_fields(uid);
}
function imgOver(id, position) {
	document.getElementById(id).style.backgroundPosition = position;
}

function imgOut(id) {
	document.getElementById(id).style.backgroundPosition = "0px 0px";
}

       
function confirmDelete(id) {
	Dialog.info($(id).innerHTML, {className: "alert",  width:320, id: "confirmMsg", recenterAuto: false, showEffectOptions: {duration: 0}, hideEffectOptions: {duration: 0}});
}          

function HoverArray() {
        this.event_handler = function(event) {
          this[$A(arguments)[1]].toggle_hover(event);
        };
        this.hoverize_link = function(link_id, hover_name) {
          Event.observe(link_id, 'mouseout', this.event_handler.bindAsEventListener(this, hover_name));
          Event.observe(link_id, 'mousemove', this.event_handler.bindAsEventListener(this, hover_name));
        };
        this.hoverize_link_onclick = function(link_id, hover_name) {
          Event.observe(link_id, 'mouseout', this.event_handler.bindAsEventListener(this, hover_name));
          Event.observe(link_id, 'click', this.event_handler.bindAsEventListener(this, hover_name));
        };
        this.late_bind_link = function(hover_name) {
                return this.event_handler.bindAsEventListener(this, hover_name);
        };
}

HoverArray.prototype = new Array();
var hover_boxes = new HoverArray();

function HoverBox(hover_name, position_cb, options) {
				options = options || {};
        /* member variables */
        this.link_tid = null;
        this.link_hid = null;
        this.current_hover_id = null;
        this.hover_name = hover_name;
        this.hover_box_id = hover_name + "_hover_box";
				this.immediate = options.immediate;
				this.populator = options.populator;

        /* member functions */
        this.hide_hover = function() {
                /* we get here once the hide_tid timer triggers */
                this.hide_tid = null;
                if (this.current_hover_id)
                {
                        Element.hide($(this.hover_box_id));
                        this.current_hover_id = null;
                }
								showSelectBoxes();
        };

        /* override the position function by passing a reference
         * to your own in position_cb
         */
        this.position_hover = position_cb || function(hover_box, parent_box) {
                Position.clone(parent_box, hover_box, {setHeight:false, setWidth:false,offsetTop:22,offsetLeft:0});
        };

        this.show_hover = function(id, parent_id) {
               /* we get here once the link_tid timer triggers */
                if (this.hide_tid) { clearTimeout(this.hide_tid); this.hide_tid = null;}
                this.link_tid = null;
                this.current_hover_id = id;
                hover_box = $(this.hover_box_id);
                this.position_hover(hover_box, $(parent_id));
                if (this.populator)
                  this.populator(parent_id, hover_box);
                else
                  hover_box.innerHTML = $(this.current_hover_id).innerHTML;
                hover_box.show();
								hideSelectBoxes();
        };

        this.clear_timers = function() {
                if (this.hide_tid) {clearTimeout(this.hide_tid);this.hide_tid = null;}
                if (this.link_tid) {clearTimeout(this.link_tid);this.link_tid = null;}
        };

        this.manage_hover = function(event) {
                this.clear_timers();
          if (event.type == "mouseout") {
                        if (this.current_hover_id) {this.hide_tid = setTimeout("hover_boxes['" + this.hover_name + "'].hide_hover()", 200); }
          }
        };

	    this.toggle_hover = function(event) {
	        /* get id from eventing node or its first parent with an id */
          element = Event.element(event);
	        while (element != null && element.id == "") {
	            element = element.parentNode;
	        }
            
	        hover_box_id = "hb_" + element.id;
	        if (event.type == "mouseout") {
            this.clear_timers();
	        	if (this.current_hover_id) {
    	            if (this.immediate) {
	                    this.hide_hover();
                    } else {
	                    this.hide_tid = setTimeout("hover_boxes['" + this.hover_name + "'].hide_hover()", 400);
                    }
                }
	        }
	        else if(event.type == "click") {
	        	if (this.link_tid) {clearTimeout(this.link_tid);}
            this.show_hover(hover_box_id, element.id);
	        }
	        else if(event.type == "mousemove") {
	        	if (this.link_tid) {clearTimeout(this.link_tid);}
                	if (this.immediate)
                        this.show_hover(hover_box_id, Event.element(event).id);
                    else
	                    this.link_tid = setTimeout("hover_boxes['" + this.hover_name + "'].show_hover('" + hover_box_id + "','" + element.id + "')", 200);						  
	        	}
	        };

        /* initialization */
        hover_boxes[hover_name] = this;
        document.write("<div id='" + this.hover_box_id + "' style='display:none'></div>");
				if (!options.not_sticky) {
	        Event.observe(this.hover_box_id, 'mouseover', this.manage_hover.bindAsEventListener(this));
	        Event.observe(this.hover_box_id, 'mouseout', this.manage_hover.bindAsEventListener(this));
				}
				
        return true;
}
/* end of hover box support */

function position_up_hover(hover_element, parent_element) {
	offsetLeft = (Position.cumulativeOffset(parent_element)[0] > 500) ? -300 : 55;
	Position.clone(parent_element, hover_element, {setHeight:false, setWidth:false,offsetTop:25,offsetLeft:offsetLeft});
}
function position_member_rating_hover(hover_element, parent_element) {
	offsetLeft = (Position.cumulativeOffset(parent_element)[0] > 500) ? -50 : 55;
	Position.clone(parent_element, hover_element, {setHeight:false, setWidth:false,offsetTop:25,offsetLeft:offsetLeft});
}
function position_help_hover(hover_element, parent_element) {
	Position.clone(parent_element, hover_element, {setHeight:false, setWidth:false,offsetTop:20,offsetLeft:10});
}
function position_privacy_hover(hover_element, parent_element) {
	Position.clone(parent_element, hover_element, {setHeight:false, setWidth:false,offsetTop:17,offsetLeft:0});
}
function position_settings_hover(hover_element, parent_element) {
	Position.clone(parent_element, hover_element, {setHeight:false, setWidth:false,offsetTop:10,offsetLeft:-40});
}

/* search box support */

function text_on_blur(object, text) { 
	if (object.value == '') {
		object.value = text;
		object.style.color = '#999';
	}
}

function text_on_focus(object, text) { 
	if (object.value == text) {
		object.value = '';
		object.style.color = '#333333';
	}
}

/* The new slidebox, now works with other things too. A slide-box consists of 2 things: 
 1. A box that contains the link that is visible, and the box that slides down (containerBox)
 2. the box that slides down on hover. (box)
*/
slideBoxes = new Hash();
function SlideBox(box, containerBox, hide_flash) {
    /* member variables */
    this.box = box;
    this.hide_tid = null;
    this.show_tid = null;
    this.visible = false;
    this.hide_flash = hide_flash;
    
    /* member functions */
    this.toggle_slide = function(event) {
	if (event.type == "mouseout") {
	    this.clear_timers();
	    this.hide_tid = setTimeout("slideBoxes['"+this.box.id+"'].hide()", 300);
	}
	else {
	    this.clear_timers();
	    this.show_tid = setTimeout("slideBoxes['"+this.box.id+"'].show()", 100);
	}
    };
    
    this.show = function() {
	show_tid = null;
	this.clear_timers();
	if (this.visible) return;
	if (this.hide_flash) {
	    hideFlash();
	}
	hideSelectBoxes();
	Effect.BlindDown(this.box, { duration: 0.5 });
	this.visible = true;
    };
    
    this.hide = function() {
	hide_tid = null;
	this.clear_timers();
	if (!this.visible) return;
	Effect.BlindUp(this.box, { duration: 0.5 });
	if (this.hide_flash) {
	    showFlash();
	}
	showSelectBoxes();
	this.visible = false;
    };
    
    this.clear_timers = function() {
	if (this.hide_tid) {clearTimeout(this.hide_tid);this.hide_tid = null;}
	if (this.show_tid) {clearTimeout(this.show_tid);this.show_tid = null;}
    };
    
    Event.observe(containerBox.id, 'mouseover', this.toggle_slide.bindAsEventListener(this));
    Event.observe(containerBox.id, 'mouseout', this.toggle_slide.bindAsEventListener(this));
    slideBoxes[box.id] = this;
}

function more_less(what) {
	[what + '_more', what + '_less'].each(Element.toggle);
	Effect.toggle(what + '_content', 'blind', {duration:0.3});
}

function setFontSize(size){
	var universe = $('universe');
	var newClassName = "fontsizer_" + size;

	universe.removeClassName('fontsizer_small');
	universe.removeClassName('fontsizer_medium');
	universe.removeClassName('fontsizer_large');
	universe.addClassName(newClassName);
	createCookie('font_size', size);
	// now change the icons for the selected font size
	var sizes = ['small', 'medium', 'large'];
	for (var i =0; i<3; i++ ) {
		fsElement = $('font_sizer_'+sizes[i]+'_link');
		fsElement.removeClassName('font_sizer_'+sizes[i]+'_link');
		fsElement.removeClassName('font_sizer_'+sizes[i]+'_link_selected');
		if (sizes[i] == size) {
			fsElement.addClassName('font_sizer_'+sizes[i]+'_link_selected');
		} else {
			fsElement.addClassName('font_sizer_'+sizes[i]+'_link');
		}
	}
}

// create a cookie with a one month expiry with the name of "name"
function createCookie(name, value, expiry) {
  var expiry_time = typeof(expiry) != 'undefined' ? expiry*1000 : (30*24*60*60*1000);

  var date = new Date();
  date.setTime(date.getTime() + expiry_time);
  var expires = "; expires="+date.toGMTString();
  document.cookie = name+"="+value+expires+"; path=/";
}

function TutorialLightBox(config, form_layout, user_tracker_after_render_cb) {
    this.config = config;
    this.page = -1;
    this.form_layout = form_layout;
    if (user_tracker_after_render_cb == null) {
       this.after_render_cb = function() {};
    } else {
       this.after_render_cb = user_tracker_after_render_cb;
    }
    this.tutorialLightbox = null;
    
    this.start = function() { 
        hideFlash();
	if ((typeof myLightbox)=='undefined') {
	    initLightbox();
	}
        this.tutorialLightbox = myLightbox;
        this.tutorialLightbox.start(this.form_layout, 0.2);
        this.page = -1;
        this.next();
    };
    this.close = function() {
        this.tutorialLightbox.end();
        showFlash();
    };
    this.next = function() {
        this.page = this.page + 1;
        this.render();
    };
    this.prev = function() {
        this.page = this.page - 1;
        this.render();
    };

    this.render = function() {

        if (this.page == 0) {
            Element.hide('tutorial_b');
        } else {
            Element.show('tutorial_b');
        }

        if (this.page == this.config.length-1) {
            Element.hide('tutorial_n');
        } else {
            Element.show('tutorial_n');
        }

        $('tutorial_text').innerHTML = $(this.config[this.page][1]).innerHTML;
        if (this.config[this.page][2] == 'R') {
            $('lightbox').style.width = '0px';
        	$('gen_tutorial').style.marginLeft = '0px';
        	$('gen_tutorial').style.marginRight = '0px';
            width = $('gen_tutorial').getWidth();
            
            targetElement = $(this.config[this.page][0]);
            heightOffset = targetElement.getHeight()/2;
            
            Position.clone($(this.config[this.page][0]), $('lightbox'), {setHeight:false, setWidth:false,offsetTop:this.config[this.page][4]-13-heightOffset,offsetLeft:-width+this.config[this.page][3]});
            Position.clone($(this.config[this.page][0]), $('trk_tut_bx_r_arr'), {setHeight:false, setWidth:false,offsetTop:this.config[this.page][4]-heightOffset,offsetLeft:-3+this.config[this.page][3]});
            Element.show('trk_tut_bx_r_arr');
            Element.hide('trk_tut_bx_t_arr');

            new Effect.ScrollTo(this.config[this.page][0], {offset: -100+this.config[this.page][4]-13-heightOffset});
        } else if (this.config[this.page][2] == 'L') {
            $('lightbox').style.width = '0px';
        	$('gen_tutorial').style.marginLeft = '0px';
        	$('gen_tutorial').style.marginRight = '0px';
            
            targetElement = $(this.config[this.page][0]);
            heightOffset = targetElement.getHeight()/2;
            
            Position.clone($(this.config[this.page][0]), $('lightbox'), {setHeight:false, setWidth:false,offsetTop:this.config[this.page][4]-13-heightOffset,offsetLeft:20+this.config[this.page][3]});
            Position.clone($(this.config[this.page][0]), $('trk_tut_bx_t_arr'), {setHeight:false, setWidth:false,offsetTop:this.config[this.page][4]-heightOffset,offsetLeft:-7+this.config[this.page][3]});
            Element.show('trk_tut_bx_t_arr');
            Element.hide('trk_tut_bx_r_arr');

            new Effect.ScrollTo(this.config[this.page][0], {offset: -100+this.config[this.page][4]-13-heightOffset});
        } else if (this.config[this.page][2] == 'T') {
            $('lightbox').style.width = '0px';
        	$('gen_tutorial').style.marginLeft = '0px';
        	$('gen_tutorial').style.marginRight = '0px';
            height = $(this.config[this.page][0]).getHeight();
            Position.clone($(this.config[this.page][0]), $('lightbox'), {setHeight:false, setWidth:false,offsetTop:height,offsetLeft:0});
            Position.clone($(this.config[this.page][0]), $('trk_tut_bx_t_arr'), {setHeight:false, setWidth:false,offsetTop:this.config[this.page][4],offsetLeft:this.config[this.page][3]});
            Element.hide('trk_tut_bx_r_arr');
            Element.show('trk_tut_bx_t_arr');

            new Effect.ScrollTo(this.config[this.page][0], {offset: -100+this.config[this.page][4]});
        } else { /* 'C' */
        	$('gen_tutorial').style.marginLeft = 'auto';
        	$('gen_tutorial').style.marginRight = 'auto';
            Position.clone($(this.config[this.page][0]), $('lightbox'), {setHeight:false, setWidth:false,offsetTop:0,offsetLeft:0});
            $('lightbox').style.left = '0px';
            $('lightbox').style.width = '100%';
            Element.hide('trk_tut_bx_r_arr');
            Element.hide('trk_tut_bx_t_arr');
    
            new Effect.ScrollTo(this.config[this.page][0], {offset: -100});
        }

        this.after_render_cb();
    };
}

function default_after_render_cb(lb) {
   if (this.page == this.config.length-1) {
      Element.show('tutorial_n');
      $('tutorial_n').getElementsBySelector('.btn_r_txt')[0].innerHTML = 'Done';
      $('tutorial_n').href = "javascript:myLightbox.end();";
   } else {        
      $('tutorial_n').getElementsBySelector('.btn_r_txt')[0].innerHTML = 'Next';
      $('tutorial_n').href = "javascript:tutorial_lb.next();";
   }
}
function trim(val) {
   return val.replace(/^\s+|\s+$/g,"");
}

function validate_field_length(field_id, length, disabled_text_id) {
  disabled_text_element = typeof(disabled_text_id) != 'undefined' ? $(disabled_text_id) : $('disabled_text');
  if ($(field_id).value.length > length) {
	  disabled_text_element.show();
    return false;
  } else {
	  disabled_text_element.hide();
    return true;
  }
}

function toggle_more_text(obj, show_less) { 
    if (show_less) {
        Element.show(obj+'_less');
        Element.hide(obj+'_more');
    } else {
        Element.show(obj+'_more');
        Element.hide(obj+'_less');
    }
}

function blind_more_text(obj, show_less) { 
    if (show_less) {
        Element.hide(obj+'_more');
        Element.show(obj+'_less');
        new Effect.BlindDown(obj+'_text');
    } else {
        new Effect.BlindUp(obj+'_text');
        Element.hide(obj+'_less');
        Element.show(obj+'_more');
    }
}

function enableScripts(name) {
    eval("magic"+name+"RunScripts = true;");
}
function disableScripts(name) {
    eval("magic"+name+"RunScripts = false;");
}

function toggleDateSelect(idPrefix, disable) {
   var date_items = ["1i", "2i", "3i"];
   for (var index=0; index < date_items.length; ++index) {
      $(idPrefix+date_items[index]).disabled = disable;
	   $(idPrefix+date_items[index]).value = "";
   }   
}

function clear_fields(field_id) {
	$(field_id).value = '';
}

function instrument_zones() {
    var zones=Element.getElementsBySelector(null, ".click_zone");
    for(var z=0; z < zones.length; z++) {
        var links;
        if(zones[z].match('a')) {
            links=[zones[z]];
        } else {
            links = zones[z].getElementsBySelector("a");
        }
        for(var l=0; l < links.length; l++) {
            links[l].observe("click", save_zone);
        }
    }
    document.cookie = "click_zone=; path=/";
}

function save_zone(event) {
    var zone_name = event.element().up(".click_zone").classNames().find(function(s) {return s.search(/^zone_/)==0;});
    if (zone_name != null) {
        document.cookie = "click_zone="+zone_name.substring(5)+"; path=/";
    }
}

function strike_through_toggle(id) {
    var elem = $(id); 
    if (elem.style.textDecoration == 'line-through') {
        elem.style.textDecoration = 'none';
    } else {
        elem.style.textDecoration = 'line-through';
    }
}
Event.observe(window, "load", instrument_zones);

function characterLimiter(divToLimit, characterLimit) {
   $(divToLimit + '_counter').innerHTML = characterLimit;
   Event.observe(divToLimit, "keyup", updateCharacterLimiter);

		var watchElement = function()	{
			interval = window.setInterval(function() {updateCharacterLimiter();}, 500);
		};
		
		var unwatchElement = function() {
			clearInterval(interval);
		};
		
		// Put eventListeners to our elements 	
		Event.observe(divToLimit, 'focus', watchElement);
		Event.observe(divToLimit, 'blur', unwatchElement);


   function updateCharacterLimiter(event) {
      var target = $(divToLimit);
      var length = target.value.length;
      var divToLimitCounter = $(divToLimit + '_counter');

      if (length < characterLimit) {
         divToLimitCounter.innerHTML = characterLimit - length;
         divToLimitCounter.addClassName('char_limit_safe');
         divToLimitCounter.removeClassName('char_limit_unsafe');
         return true;      
      } else if (length == characterLimit) {
         divToLimitCounter.innerHTML = 0;
         divToLimitCounter.addClassName('char_limit_unsafe');
         divToLimitCounter.removeClassName('char_limit_safe');
      } else {
         target.value = target.value.substring(0, characterLimit);
         divToLimitCounter.innerHTML = 0;
         divToLimitCounter.addClassName('char_limit_unsafe');
         divToLimitCounter.removeClassName('char_limit_safe');
         return false;
      }
   }
}

function shouldAutoScrollDown(objDiv) {
   return (objDiv.scrollHeight - objDiv.getHeight() - 10) <= objDiv.scrollTop;
}

var PeriodicUpdater = Class.create({
   initialize: function(divToUpdate, interval, file, params, options) {
      this.divToUpdate = divToUpdate;
      this.interval = interval;
      this.file = file;
      this.pendingRequest = false;
      this.pauseLockCount = 0;
      this.disabled = false;
      if (typeof(options) == 'undefined') { 
         this.options = {}; 
      } else {
         this.options = options;
      }
      this.params = params;
      this.periodicExecuter = new PeriodicalExecuter(this.getUpdate.bind(this), this.interval);
   },

   onSuccess: function() {
      var updater = this;
      return function(transport){         
         if (transport.status != 0) {
            if (updater.pauseLockCount == 0) {
               var objDiv = $(updater.divToUpdate);
               var updateScrollTop = false;
               if (shouldAutoScrollDown(objDiv)) { updateScrollTop = true; }

               /* Update content */
               if (updater.options['position'] == 'bottom') {
                  $(updater.options['insert_position']).insert({before:transport.responseText});
               } else {
                  $(updater.divToUpdate).innerHTML = transport.responseText;
                  setTimeout(function() {
                     transport.responseText.evalScripts();
                  }, 10);
               }              
               if (updateScrollTop) {
                  objDiv.scrollTop = objDiv.scrollHeight;
               }
            }
         }
      };
   },

   onComplete: function() {
      var updater = this;
      return function(transport){
         updater.pendingRequest = false;
      };
   },
   /* pause, continue functionality - implemented using a counter */
   lock: function() {
      this.pauseLockCount += 1;
   },
   unlock: function() {
      this.pauseLockCount -= 1;
   },   
   stop: function() {
      this.periodicExecuter.stop();
   },
   updateInterval: function(interval) {
      if (interval != this.interval) {
         this.periodicExecuter.stop();
         this.interval = interval
         this.periodicExecuter = new PeriodicalExecuter(this.getUpdate.bind(this), interval);
      }
   },
   setParams: function(params) {
      this.params = params;
   },
   getUpdate: function() {
      if (!this.pendingRequest) {
         this.pendingRequest = true;
      
         new Ajax.Request(this.file,
         {
            method: 'post',
            parameters: this.params,
            onSuccess: this.onSuccess(),
            onComplete: this.onComplete()
          });    
      }
   }
});

function display_txt_fld_list(keywords,value,fld){
	var suggested_choices = [];
	keywords.each(function(k){
	  if (k.toLowerCase().startsWith(value.toLowerCase()) && value.length >= 1) {
	    suggested_choices.push(k);
	  }
	});
	formatted_choices = format_choices(suggested_choices);
   return formatted_choices;
};

function format_choices(choices){
  text = '';
  text += '<ul>';
  choices.each(function(c){
    text += '<li>'+c+'</li>';
  });	
  return text += '</ul>';
};


Ajax.RemoteAutocompleter = Class.create(Autocompleter.Base, {
  initialize: function(element, update, options) {
    this.baseInitialize(element, update, options);
    this.choices = options.choices;
  },

  getUpdatedChoices: function() {
    choices = display_txt_fld_list(this.choices,this.getToken(),'to');
    this.updateChoices(choices);
  }
});

function privacy_manager_set_privacy(id, value, privacy_manager_id, table_name) {
  /* hide drop down, icon, and show spinner */
  hover_boxes['privacy'].hide_hover();
  pm_box = $(privacy_manager_id);

  pm_box.className = 'privacy_manager_box';
  $('pm_'+ privacy_manager_id + '_pro_ind').show();

  var privacyManagerSetPrivacyonComplete = function(id) {
      var _hb_id = 'hb_' + id;
      var _id = id;
      return function(transport){
        $(_hb_id).innerHTML = transport.responseText;
        setTimeout(function(){
          transport.responseText.evalScripts();
        }, 10);          
      };
   };

  var params = { id: id};
  params[table_name+"[view_privacy_setting]"] = value;
  new Ajax.Request('/' + table_name + '/set_privacy', {
    method: 'post',
    parameters: params,
    onComplete: privacyManagerSetPrivacyonComplete(privacy_manager_id)
    });
};
function privacy_manager_update(id, icon_class) {
  pm_box = $(id);
  pm_box.addClassName('icon_link_img_std');    
  $('pm_'+ id + '_pro_ind').hide();
  pm_box.addClassName(icon_class);
};

function clear_announcement(key, value, expiry) {
  createCookie(key, value, expiry);
  $('ann_panel').hide();
  return false;
};

function setDateSelectValue(event) {
  var divId = event.element().id.gsub(/(.*)_.*/, '#{1}');
  var day = $(divId+'_day').value;
  var month = $(divId+'_month').value;
  var year = $(divId+'_year').value;
  
  if (day!="" && month!="" && year!="") {
    $(divId).value = [year, month, day].join("-");
  } else {
    $(divId).value="";
  }
}

function isNumeric(string) {
    return(!isNaN(parseFloat(string)));
}

function isInteger(string) {
    return(string.match(/^\d+$/)!==null);
}

// Note that this is not always garunteed to return false if no match found. 
// this is because of the edge cases around "."
function processPartialNumerical(textField) {
    if(textField.value.endsWith(".")) {
        if (textField.value==".") {
            textField.value = "0.";
        }
        return true;
    } 
    if(!isNumeric(textField.value)) {
        return false;
    }
    return true;
}

/* User profile hover management */
var current_up_id = 0;
var up_hover_box = null;
var up_hovers_html = {};
function up_populator_success(transport) {
  new_up_id = transport.request.url.split("/").last();
  up_hovers_html[new_up_id] = transport.responseText;
  
  if (new_up_id == current_up_id)
    up_hover_box.down(".replaceable").innerHTML = transport.responseText;
}

function up_populator(link_id, hover_box) {
  user_id = link_id.split("_")[1];
  current_up_id = user_id;
  up_hover_box = hover_box;
  
  hover_box.innerHTML = $('up_shell').innerHTML;
  if (up_hovers_html[user_id]) {
    up_hover_box.down(".replaceable").innerHTML = up_hovers_html[user_id];
  } else {
    req = new Ajax.Request("/user_profiles/hover/" + user_id, {
      method: 'get',
      onSuccess: up_populator_success
    });
  }
}

function updateAddictedToOthersTextBox(event) {
  var element = Event.element(event);

  if (element.value == 'Others') {
    $('temp_other_tracker_setup_field_Addicted_to').disabled = !element.checked;
  }
}

function calculateAddictedToOther(event) {
  var addictions = [];
  var othersSelected = false;
  $('edit_form').getElementsBySelector(".temp_chk_addicted_to").each(function(node){
    if (node.checked) {
      if (node.value == 'Others') {
        othersSelected = true;
      } else {
        addictions.push(node.value);
      }
    }
  });
  normalized_names = addictions.map( function(name) { return name.toLowerCase(); } );
  
  if (othersSelected) {
    $('temp_other_tracker_setup_field_Addicted_to').value.split(',').each(function(item) {
      value = item.replace(/^\s+|\s+$/g,"");
      if (value.length > 0) {
        if (!normalized_names.include(value.toLowerCase())) {
          addictions.push(value);
          normalized_names.push(value.toLowerCase());
        }        
      }
    });
  }

  $('tracker_setup_field_Addicted-to').value = addictions.join(",");
}

function validate_email_fields() {
  var email_errors = new Array();

  if ($("sender_name").value.length == 0) {
    email_errors.push("Your name");
  }

  if (!validate_email($("sender_email").value)) {
    email_errors.push("Your email");
  }  

  if (!validate_email($("recipient_email").value)) {
    email_errors.push("Friend's email");
  }  

  if ($("verification_code").value.length == 0) {
    email_errors.push("Code");
  }  

  if (email_errors.length > 0) {
    var error_message = 'Invalid ';

    for (var index = 0; index < email_errors.length; ++index) {
      var item = email_errors[index];
      error_message += item;
      if (index != email_errors.length-1) 
        error_message += ', ';
    }

    $('ef_errors').innerHTML = error_message;
    $('ef_errors').show();
  } else {
    $('ef_errors').hide();
    $('ef_submit_btn').hide();
    $('ef_submitting').show();
  }
  return email_errors.length == 0;
}

// wrapper around the user_data/save AJAX call. 
// Args: 
// timestamp: timestamp for the values
// values: hash of key-value pairs. Here, each value must be a string that can be used to construct 
//         a user-data object of its key.
// onSuccess: a callback called when the AJAX call is successful. A hash consisting of errors will be passed
//         to this callback.
// (Note: The different field types (time-independent, time-specific and default are handled on the server)
// 
function saveUserData(userId, relativeId, timestamp, values, sourceId, sourceType, onSuccess) {
    var userData = new Hash(values);
    var timestampString = (timestamp.getFullYear())+"/"+(timestamp.getMonth()+1)+"/"+timestamp.getDate()+" "+timestamp.getHours()+":"+timestamp.getMinutes()+":"+timestamp.getSeconds();
    var params = {'user_id': userId, 'timestamp': timestampString, 'source_id': sourceId, 'source_type': sourceType};

    if(relativeId !== null) {params['relative_id'] = relativeId; }

    if (userData.size()===0) {
        return;
    }
    userData.each(function(pair) {
            params["user_data["+pair.key+"]"] = pair.value;
        }.bind(this));
    
    new Ajax.Request('/user_data/save', {
            method: 'post',
            parameters: params,
            onSuccess: function(transport) {
                var errors = transport.responseText.evalJSON();
                if(onSuccess !== null) {
                    onSuccess(errors);
                }
            }});
    
}

function saveUserAppSetting(userId, appName, settingName, value) {
    var params = {'user_id': userId, 'user_app_name': appName, 'setting_name': settingName, 'value': value};
    new Ajax.Request('/user_app_settings/save', {
            method: 'post',
            parameters: params
    });
}

