// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults

function limitText(limitField, limitNum) {
    if (limitField.value.length > limitNum) {
        limitField.value = limitField.value.substring(0, limitNum);
    } 
}


// focus on username when login page is visible
document.observe('dom:loaded', function(){
	            if ( $("login") ) {	$("login").focus() }	
                 });


// pulldown master question controls whether slave section is shown, pass question ids
function control_other_select(args){

   // determine if an slave element should be shown based on 
   // master element and args.on or args.except param
   var should_show_slave = function(master_element, args){
      if(args.on != null){
        if (args.on.match(',')) { // match any
          var values = args.on.split(',')
          var matched = false 
          for (var i=0; i<values.length; i++) {
            if (master_element.value == values[i]) {
              matched = true
            }
          }
          return (matched)
        } 
        else {
         return (master_element.value == args.on)
        }
      }else if(args.except != null){
        if (args.except.match(',')) { // exclude all
          var values = args.except.split(',')
          var not_matched = true 
          for (var i=0; i<values.length; i++) {
            if (master_element.value == values[i]) {
              not_matched = false
            }
          }
          return (not_matched)
        } 
        else {
         return (master_element.value != args.except)   
        }         
      }else{
         alert("missing on: or except: third parameter in should_show_slave()");
      }
   }

   // hide slave question upon document load if master question value is not control_value
   document.observe('dom:loaded', function() { 
		       if( ! should_show_slave($("q_widget_" + args.master_id), args) ){ 
                          $("sec_" + args.slave_id).hide() 
                       }	
	            }); 

   // on change callback, master can make slave appear and disappear
   var show_hide_widget = function(event){
      var element = event.element();
      if ( should_show_slave(element, args) ){
	 //new Effect.Appear($("sec_" + args.slave_id))
	 $("sec_" + args.slave_id).show();
      }else{
	 $("q_widget_" + args.slave_id).value = ""; // user might think it doesn't go away, just hides
	 //new Effect.Fade($("sec_" + args.slave_id))
	 $("sec_" + args.slave_id).hide();
      }
    }

    $("q_widget_" + args.master_id).observe("change", show_hide_widget)

}

// radio master question controls whether slave section is shown, pass question ids
// {master_id:M, slave_id:S, on:[M_value_a, M_value_b, ...], off:[M_value_0, M_value_1, ...] }
function control_other_radio(args){

   if ( args.on == null ) { 
      alert('missing on: third arg in control_other_radio function');
      return false;
   }

   var slave_html_id = 'sec_' + args.slave_id;

   for ( var i = 0; i < args.on.length; i++ ) {
     var master_html_id = 'q_widget_' + args.master_id + '_' + args.on[i]
  
     var should_show_slave = function(master_element){
       if ( master_element) {
         return master_element.checked;
       }
       return false;
     }
  
     // hide slave question upon document load if master question value is not control_value
     document.observe('dom:loaded', function() { 
  		       if( ! should_show_slave($(master_html_id)) ){ 
                            $(slave_html_id).hide() 
                         }	
  	            }); 
  
     // on change callback, master can make slave appear and disappear
     var show_hide_widget = function(event){
       var element = event.element();
       if ( should_show_slave(element, args) ){
  	 //new Effect.Appear($("sec_" + args.slave_id))
  	 $(slave_html_id).show();
       }else{
  	 $(slave_html_id).value = ""; // user might think it doesn't go away, just hides
  	 //new Effect.Fade($("sec_" + args.slave_id))
  	 $(slave_html_id).hide();
       }
     }
  
     $(master_html_id).observe("click", show_hide_widget);
   }
   
   // to make slave dissapear when other radio buttons are clicked
    var hide_widget = function(event){
      $(slave_html_id).hide();
    }

    // turn off others on click
    for ( var j = 0; j < args.off.length; j++ ) {
      var sub_master_html_id = 'q_widget_' + args.master_id + '_' + args.off[j];
      $(sub_master_html_id).observe("click", hide_widget);
    }
}


// checkbox master question controls whether slave section is shown, pass question ids
function control_other_checkbox(master_id, slave_id){

	// hide slave question upon document load if master question is not checked
	document.observe('dom:loaded', function() { 
		if(! $("q_widget_" + master_id).checked){ $("sec_" + slave_id).hide() }	
	}); 

	// on change callback, master can make slave appear and disappear
	var show_hide_widget = function(event){

		var element = event.element();
		if (element.checked){
		   //new Effect.Appear($("sec_" + slave_id))
		   $("sec_" + slave_id).show()
		}else{
		   $("q_widget_" + slave_id).value = ""; // user might think it doesn't go away, just hides
		   //new Effect.Fade($("sec_" + slave_id))
		   $("sec_" + slave_id).hide()
		}
	}

	$("q_widget_" + master_id).observe("click", show_hide_widget)

}


// a checkbox controls the visibility of an emement
// naming convention is "visible" + control widget id + element id 
// param1: checkbox_id
// param2: id of element to be controlled
function visible_check_id(check_id, element_id){

   // hide slave question upon document load if master question is not checked
   document.observe('dom:loaded', function() { 
		       if(! $("q_widget_" + check_id).checked){ $(element_id).hide() }	
	            }); 
   
   // on change callback, master can make slave appear and disappear
   var show_hide_widget = function(event){
      
      var element = event.element();
      if (element.checked){
	 //new Effect.Appear($(element_id))
	 $(element_id).show()
      }else{
         // reset all checkboxes
         $(element_id).select("input[type=checkbox]]").each(function(checkbox){
                                                               checkbox.checked = false;
                                                            });

         // reset all textfields
         $(element_id).select("input[type=text]]").each(function(textfield){
                                                               textfield.value = "";
                                                            });


	 //new Effect.Fade($(element_id))
	 $(element_id).hide();
         
      }
   }
   
   $("q_widget_" + check_id).observe("click", show_hide_widget)

}


// a textfield controls the visibility of an emement
// naming convention is "visible" + control widget id + element id 
// param1: textfield_id
// param2: id of element to be controlled
function visible_text_id(textfield_id, element_id){

   // hide slave question upon document load unless master question has content
   document.observe('dom:loaded', function() { 
		       if(! $("q_widget_" + textfield_id).value.length){ $(element_id).hide() }	
	            }); 
   
   // on change callback, master can make slave appear and disappear
   var show_hide_widget = function(event){
      
      var element = event.element();
      if (element.value.length){
	 //new Effect.Appear($(element_id))
	 $(element_id).show();
      }else{
         // reset all checkboxes
         $(element_id).select("input[type=checkbox]]").each(function(checkbox){
                                                               checkbox.checked = false;
                                                            });

         // reset all textfields
         $(element_id).select("input[type=text]]").each(function(textfield){
                                                               textfield.value = "";
                                                            });


	 //new Effect.Fade($(element_id))
	 $(element_id).hide();
      }
   }
   
   $("q_widget_" + textfield_id).observe("keyup", show_hide_widget)

}




// textbox master question controls whether slave section is shown, pass question ids
function control_other_textfield(master_id, slave_id){

	// hide slave question upon document load if master question answer is longer than 0
	document.observe('dom:loaded', function() { 
		if(! $("q_widget_" + master_id).value.length){ $("sec_" + slave_id).hide() }	
	}); 

	// on change callback, master can make slave appear and disappear
	var show_hide_widget = function(event){
           var slave_element = $("sec_" + slave_id);
	   var element = event.element();
	   if (element.value.length){
	      //new Effect.Appear(slave_element);
	      slave_element.show();
	   }else{
	      $("q_widget_" + slave_id).value = ""; // user might think it doesn't go away, just hides
	      //new Effect.Fade(slave_element)
	      slave_element.hide();
	   }
	}

	$("q_widget_" + master_id).observe("keyup", show_hide_widget)

}

// sum of multiple textfields control the visibility of multiple emements,
// i.e. if one of the textfields has a value greater than zero, make slave classes appear
// param1: textfield_ids array
// param2: class of element to be controlled
function visible_count_classes(textfields, element_class){

	// sums all the textboxes
	var field_sum = function (textfields) {
		var count = 0;
		textfields.each(function(x){
			value = $("q_widget_" + x).value;
			value = parseInt(value); // I hate javascript
			if (! isNaN(value) ) { // wtf
				count = count + value;
			}	
		});
		return count;
	}

	// hide slave class upon document load unless master questions > 0
	document.observe('dom:loaded', function() { 
		if(! field_sum(textfields) ){ 
			$$('.' + element_class).each(function(x){ x.hide(); })
		}	
	}); 

	// on change callback, master can make slave appear and disappear
	var show_hide_widget = function(event, textfields){

		// if element has length but is not zero
		if (field_sum(textfields) > 0){
		   $$('.' + element_class).each(function(x){ /* new Effect.Appear(x) */ x.show()})
		}else{ // clear and hide

			// loop over every element of class and do stuff to it
			$$('.' + element_class).each(function(x){

				// reset all checkboxes
				x.select("input[type=checkbox]]").each(function(checkbox){
					checkbox.checked = false;
				});

				// reset all textfields
				x.select("input[type=text]]").each(function(textfield){
					textfield.value = "";
				});
                                x.hide();
	                        //new Effect.Fade(x) // fade too slow, can't keep up with changes

			})

		}
	}

	textfields.each(function(textfield_id){
		//$("q_widget_" + textfield_id).observe("keyup", show_hide_widget, [1,2,3])
		Event.observe($("q_widget_" + textfield_id), 'keyup', show_hide_widget.bindAsEventListener(this, textfields));
	})

}


// install tooltip onclick handlers
document.observe('dom:loaded', function(){
                    // find each id beginning with "tip_icon_"
                    $$("[id^=tip-icon-]").each(function(x){
                                                  x.observe("click", reveal_tip)
                                               });
});





// when tip icon is clicked on, tip is revealed
function reveal_tip(event){

   // get tooltips id from tip_icon_id and then get corresponding tip_text element
   var index_of_id = 1 + event.element().id.lastIndexOf("-")
   var id = event.element().id.substring(index_of_id);
   var tip_text = $("tip-text-" + id);

   if( tip_text.visible() ){
      tip_text.hide();
   }else{
      tip_text.show()
   }

}


function imposeMaxLength(e, Object, MaxLen)
{
  var keynum;
  if(window.event) // IE
    {
    keynum = e.keyCode;
    }
  else if(e.which) // Netscape/Firefox/Opera
    {
    keynum = e.which;
    }
  
  // always allow backspace or delete
  if (keynum == 8 || keynum == 46) {
    return true;
  }
  
  //return (Object.value.length <= MaxLen);

  // remove carriage returns for counting
  var no_cr_value = Object.value.replace(/\r/g, '');
  
  if (no_cr_value.length <= MaxLen) {
    return true;
  }
  else {
    var msg = 'You have entered more than the ' + MaxLen + ' characters allowed [' + no_cr_value.length + '].' + "\n";
    
    var over_count = no_cr_value.length - MaxLen;
    if ( over_count == 1 ) {
      over_count += ' character';
    }
    else {
      over_count += ' characters';
    }
    msg += 'Please remove ' + over_count + ' from your text.';
    alert( msg );
    return false;
  }
}

// takes Simple Question ID and Max Length as args
function check_textarea_length( sqid, ml ) {
  var ta_elements = $$( '.' + sqid );

  // should only be 1
  var ta_no_cr = ta_elements[0].value.replace( /\r/g, '' );

  if ( ta_no_cr.length > ml ) {
    return false;
  }

  return true;
}

// args has these keys
// master_id: simple question_id [like 'Q4a']
// slave_id: array of values of dependent simple question_ids
// can only use 1 of 'enable', 'disable'
// enable: array of values to enable slave_id questions, otherwise disabled [can use empty array for null or no value]
// disable: array of value to disable slave_id questions
function disable_question( args ) {
  
  // move data out of args object
  var tmp;
  tmp = '.' + args.master_id;
  var master_elements = $$( tmp );
  var mids = [];
  for( var i = 0; i < master_elements.length; i++ ) {
    mids.push( master_elements[i].id );
  }

  var slids = [];
  for( var i = 0; i < args.slave_id.length; i++ ) {
    slids.push( args.slave_id[i] );
  }

  var enbl = [];
  var dsbl = [];
  if ( args.enable ) {
    for( var i = 0; i < args.enable.length; i++ ) {
      enbl.push( args.enable[i] );
    }
    dsbl = false;
  }
  else if ( args.disable ) {
    for( var i = 0; i < args.disable.length; i++ ) {
      dsbl.push( args.disable[i] );
    }
    enbl = false;
  }
  else {
    alert( 'disable_question must be called with either enable or disable arguments' );
  }

  // main update function
  var update_slaves = function( m, sl, e, d ) {

    // enable arg passed in
    if ( e ) {

      var disable = true;
      for( var i = 0; i < m.length; i++ ) {
      
        // get out if a match
        if ( ! disable ) { break; }
  
        var val = $( m[i] ).getValue();
     
        // nothing to match
        if ( e.length < 1 ) {
          if ( ! val ) {
            disable = false;
          }
        
          // get out either way
          break;
        }
        else {
          for ( var j = 0; j < e.length; j++ ) {
            if ( val == e[j] ) {
              disable = false;
  	    break;
            }
          }
        }
      }
    }

    // disable arg passed in
    else if ( d ) {
    
      var disable = false;
      for( var i = 0; i < m.length; i++ ) {
      
        // get out if a match
        if ( disable ) { break; }
  
        var val = $( m[i] ).getValue();
     
        // nothing to match
        if ( d.length < 1 ) {
          if ( ! val ) {
            disable = true;
          }
        
          // get out either way
          break;
        }
        else {
          for ( var j = 0; j < d.length; j++ ) {
            if ( val == d[j] ) {
              disable = true;
  	    break;
            }
          }
        }
      }
    }

    for ( var i = 0; i < sl.length; i++ ) {
      var t = '.' + sl[i];
      var s_elem = $$( t );

      for( var j = 0; j < s_elem.length; j++ ) {
        if ( disable ) {
          // clear value if disabled
	  s_elem[j].setValue( '' );
	  s_elem[j].disable();
        }
        else {
          s_elem[j].enable();
        }
      }
    }
  }

  // hide slave question upon document load if master question value is not control_value
  document.observe('dom:loaded', function() { 
    update_slaves( mids, slids, enbl, dsbl );
  }); 
 
  // wrapper to be called without args
  var upd_slv = function() {
    update_slaves( mids, slids, enbl, dsbl );
  }
 
  for( var i = 0; i < mids.length; i++ ) {
    $( mids[i] ).observe("click", upd_slv)
  }
}


// this function forces the input_elt field into a comma-padded decimal format.
function enforce_commas (input_elt) {
  input_elt.value = insert_commas(input_elt.value);
}

// returns the number with commas inserted every 3 digits.  e.g. 12345678 becomes '12,345,678'
// max two decimal places.
function insert_commas (number) {
  var oldstr = number.toString();
  oldstr = oldstr.replace(/[^0-9\.]/g, ''); // strip all non-digit-or-decimals to start
  
  var wpmatch = oldstr.match(/^\d*/);
  var wholepart = wpmatch ? wpmatch[0] : '';
  var dpmatch = oldstr.match(/\.\d*$/);
  var decimalpart = dpmatch ? dpmatch[0] : '';
  decimalpart = decimalpart.substr(0, 3); // max two decimal places
  
  var newstr = '';
  while (wholepart.length > 3) {
    var threedigits = wholepart.substr(wholepart.length-3, 3);
    newstr = ',' + threedigits + newstr;
    wholepart = wholepart.substr(0, wholepart.length-3);
  }
  newstr = wholepart + newstr + decimalpart;
  
  return newstr;
}


// everyone's favorite.  make a collection of checkboxes act sort
// of like radio buttons.  Zero or one item will be selected at any time.
function enforce_radio_checkbox (checkbox_elt, checkbox_ids) {
  if (checkbox_elt.checked) {
    for (var i in checkbox_ids) {
      var id = 'q_widget_' + checkbox_ids[i];
      if (checkbox_elt.id != id) {
        var othercb = document.getElementById(id);
        if (othercb) {
          othercb.checked = false;
        }
      }
    }
  }
}



