/****************************************************************************
  Filename: labeler.js
  Created: 2009-04-16
  Last Modified: 2009-04-16
  
  Description:
     Contains utility functions for the labeler form.

  Dependencies: none
  
  Contributors (chronological order, starting with originating author):
    Matt Meyer (MM)

  Revision History:
    MM, 2009-04-16 -
      Created
      

 ****************************************************************************/

/****************************************************************************
  validateInput - Checks keystrokes for valid input based on validate string.

  Arguments:
    event (Event object) - Event that's being triggered
    validate (string, regex) - Validation expression

  Returns: boolean if value is valid
    
  Notes:
    The onKeyPress event is supposed to return the ASCII value of the 
    character passed to the box in the keyCode property.  Firefox returns 
    the key code of the pressed keys (incorrect).  However, it does return 
    the ASCII value in the charCode property.  Unfortunately, browser support
    for this property is weak, but very good for keyCode (FF is the only 
    misbehaving browser).
    
    This sets a property on the field being checked to flag if a jump is 
    permitted or not (only permit on successful input).
 ****************************************************************************/
function validateInput(event, validate){
	var element = (event.target) ? event.target : event.srcElement;
	element.doJump = false;
	var key = (event.charCode!=undefined) ? event.charCode : event.keyCode;	
	if(key<32 || key==127){ return true; }	//control characters, not my deal.
	key = String.fromCharCode(key);
	return (element.doJump=validate.test(key));
}

/****************************************************************************
  fieldJump - Jumps fields if the condition is met

  Arguments:
    event (Event object) - Event that's being triggered
    condition (string, regex) - Value condition that's required for the jump.
    target_id (string) - the target element ID for the new focus

  Returns: void
    
  Notes:
    Should be attached to KeyUp event so it fires after the input 
    is validated by the KeyPress events.  Also, only jumps if the jump
    flag on the element is set to true (happens in KeyPress event).
 ****************************************************************************/
function fieldJump(event, condition, target_id){
	var element = (event.target) ? event.target : event.srcElement;
	if(element.doJump && condition.test(element.value)){
		var focus_element = getAspElementById(target_id);
		if(focus_element){
			focus_element.focus();
		}
	}
	element.doJump = false;
}

// ID values for accessing the MountEditor elements
id_prefix = false;
id_mount_input = "MountInput";
id_mount_label = "MountLabel";
id_mount_preview = "MountPreview";
id_mount_count = "MountCount";
id_mount_total = "MountCharCount";
// Default Preview Values
preview_default = [
	"LINE 1",
	"LINE 2",
	"LINE 3"
];

/****************************************************************************
  initializeIdPrefix

  Arguments:
    generated_id (string) - Generated ASP.net ID
    assumed_id (string) - ID Value Set in Markup

  Returns: void
  
  Description:
    Sets the id_prefix to use in getAspElementById()
 ****************************************************************************/
function initializeIdPrefix(generated_id, assumed_id){
	if(id_prefix)return;
	id_prefix = generated_id.replace(assumed_id,"");
}
/****************************************************************************
  initializeIdPrefix

  Arguments:
    request_id (string) - "ID" of element to get

  Returns: DOM Element requested
  
  Description:
    Mimics getElementById for ASP.Net controls, appending the id_prefix
    detected in initializeIdPrefix()
 ****************************************************************************/
function getAspElementById(request_id){
	return document.getElementById(id_prefix + request_id);
}

/****************************************************************************
  enforceTypedLimits

  Arguments:
    event (Event Object) - JavaScript Event

  Returns: boolean to process key press
  
  Description:
    Event function attached to keypress.  If capacities are reached, 
    disregards the kestroke.
 ****************************************************************************/
function enforceTypedLimits(event){
	var element = (event.target) ? event.target : event.srcElement;
	var key = (event.charCode!=undefined) ? event.charCode : event.keyCode;
	var skip = (event.modifiers) ? (event.modifiers & (event.ALT_MASK|event.CONTROL_MASK)) : (event.ctrlKey || event.altKey)
	
	//Control characters, or Alt/Control being held, not my deal
	if(key<32 || key==127 || skip) return true;
	
	if(!id_prefix){
		initializeIdPrefix(element.id.substring(0,element.id.length-1),id_mount_input);
	}
	
	element.lineMax = parseInt(element.getAttribute('line-max'));
	
	var count_element = getAspElementById(id_mount_total);
	var char_max = parseInt(count_element.getAttribute('total-max'));
	var total = 0;
	var line = 1;
	
	if(element.value.length >= element.lineMax){ //line check first
		return false;
	}
	while(current=getAspElementById(id_mount_input+line)){
		total += current.value.length;
		if(total >= char_max) return false;
		line+=1;
	}
	return true;
}

/****************************************************************************
  calculateAndUpdate

  Arguments:
    event (Event Object) - JavaScript Event

  Returns: void
  
  Description:
	Attached to KeyUp events
    Runs over fields and does dome preliminary calculations on the caps.
    Updates the content to reflect the values.
 ****************************************************************************/
function calculateAndUpdate(event) {
	if(!id_prefix){ //post key processing (use to calculate total for rendering)
		var element = (event.target) ? event.target : event.srcElement;
		initializeIdPrefix(element.id.substring(0,element.id.length-1),id_mount_input);
	}
	
	var count_element = getAspElementById(id_mount_total);
	if(count_element==null || !count_element) return;
	
	count_element.totalMax = parseInt(count_element.getAttribute('total-max'));
	count_element.charCount = 0;
	var line = 1;
	var current;
	while(current=getAspElementById(id_mount_input+line)){
		current.lineMax = parseInt(current.getAttribute('line-max'));
		count_element.charCount += current.value.length;
		line+=1;
	}
	if(count_element.charCount > 0){
		updateDisplay();
	}else{
		resetDisplay();
	}
	return true;
}

/****************************************************************************
  enforcePastedLimits

  Arguments:
    event (Event Object) - JavaScript Event

  Returns: false
  
  Description:
    Attaches to Paste events, disables all pasting (for now)
 ****************************************************************************/
function enforcePastedLimits(event){
	return false;
}

/****************************************************************************
  updateDisplay

  Arguments: none

  Returns: void
  
  Description:
    Updates the preview text and all line limit counter elements
 ****************************************************************************/
function updateDisplay(){
	var input = false;
	var preview = false;
	var label = false;

	var count_element = getAspElementById(id_mount_total);
	var remaining = count_element.totalMax - count_element.charCount;
	
	var line_remaining = 0;
	var line = 1;
	while(input = getAspElementById(id_mount_input+line)){
		preview = getAspElementById(id_mount_preview+line);
		label = getAspElementById(id_mount_count+line);
		
		line_remaining = input.lineMax - input.value.length;
		if(remaining < line_remaining){
			line_remaining = remaining;
		}
		
		preview.innerHTML = "&nbsp;" + input.value.replace("<","&lt;").replace(">","&gt;").toUpperCase() + "&nbsp;";
		label.innerHTML = "(" + line_remaining + " characters remaining)";
		
		line++;
	}
	count_element.innerHTML = "(" + remaining + " total characters remaining)";
}

/****************************************************************************
  resetDisplay

  Arguments: none

  Returns: void
  
  Description:
    Sets all preview and counters back to the defaults (no input)
 ****************************************************************************/
function resetDisplay(){
	var count_element = getAspElementById(id_mount_total);
	var input = false;
	var preview = false;
	var label = false;
	var line = 1;
	while(input = getAspElementById(id_mount_input+line)){
		preview = getAspElementById(id_mount_preview+line);
		label = getAspElementById(id_mount_count+line);
		preview.innerHTML = preview_default[line-1];
		label.innerHTML = "(" + input.getAttribute('line-max') + " characters remaining)";
		line++;
	}
	count_element.innerHTML = "(" + count_element.getAttribute('total-max') + " total characters remaining)";	
}

/****************************************************************************
  triggerAsyncUpdate

  Arguments:
    sender (??) - needed to match function signature for .Net
    args (??) - needed to match function signature for .Net

  Returns: void
  
  Description:
    Explicitly updates content on AJAX callbacks from .Net
    Passes no event (initializeIdPrefix should have already run)
 ****************************************************************************/
function triggerAsyncUpdate(sender, args){
	calculateAndUpdate(false);
}