/**
 *
 * The Alert function checks the value of text box for a value between 1 and 10
 *
 * @contructor
 */

function Alert( alert_id, message_id, close_id ) {

   this.alert_id = alert_id;
   this.message_id = message_id;
   this.close_id = close_id;
   this.guess = null;

}

/**
 * init is a subclass of Guess
 *
 * @member Guess
 *
 * @return nothing
 */

Alert.prototype.init = function() {

  this.node_alert   = document.getElementById(this.alert_id);
  this.node_message = document.getElementById(this.message_id);
  this.node_close   = document.getElementById(this.close_id);

  var obj = this;

  browser.addEvent(this.node_alert, "keydown", function(event) {handleAlertKeyDownEvent(event, obj ); },     true);
  browser.addEvent(this.node_close, "click",   function(event) {hideAlert( obj ); },  true);

}

/**
 * hideAlert
 *
 * @param ( id ) id of alert box to hide
 *
 * @return nothing
 *
 */

function hideAlert( alert_obj ) {

  alert_obj.node_alert.style.display = "none";
  alert_obj.node_alert.setAttribute("aria-hidden", "true");

  browser.releaseMouseCapture( alert_obj.node_alert, 
                               alert_obj.mouse_click_event,  
                               alert_obj.mouse_down_event,  
                               alert_obj.mouse_move_event,  
                               alert_obj.mouse_up_event  
                              );

  alert_obj.guess.node_text.focus();
  alert_obj.guess.node_text.select();

 }

 /**
* showAlert
*
* @param ( string ) message is the text string for the dialog
*
* @return nothing
*
*/

 function showAlert( alert_obj, message ) {

   alert_obj.node_message.innerHTML = message;

   var obj = alert_obj;

   alert_obj.mouse_click_event = function(event) {handleAlertMouseClickEvent(event, obj ); };
   alert_obj.mouse_down_event  = function(event) {handleAlertMouseDownEvent(event, obj ); };
   alert_obj.mouse_move_event  = function(event) {handleAlertMouseMoveEvent(event, obj ); };
   alert_obj.mouse_up_event    = function(event) {handleAlertMouseUpEvent(event, obj ); };

   browser.setMouseCapture( alert_obj.node_alert, 
                            alert_obj.mouse_click_event,  
                            alert_obj.mouse_down_event,  
                            alert_obj.mouse_move_event,  
                            alert_obj.mouse_up_event  
                          );

   alert_obj.node_alert.style.display  = "block";
   alert_obj.node_alert.style.position = "absolute";
   alert_obj.node_alert.style.top= ( (alert_obj.guess.node_box.offsetHeight - alert_obj.node_alert.offsetHeight ) / 2 ) + browser.calculateOffsetTop( alert_obj.guess.node_box ) + "px";
   alert_obj.node_alert.style.left = ( (alert_obj.guess.node_box.offsetWidth  - alert_obj.node_alert.offsetWidth  ) / 2 ) + browser.calculateOffsetLeft( alert_obj.guess.node_box ) + "px";
   alert_obj.node_alert.setAttribute("aria-hidden", "false");
   alert_obj.node_alert.focus();

}

/**
 * handleAlertKeyDownEvent
 *
 * @param ( event object ) event
 *
 * @return nothing
 *
 */

function handleAlertKeyDownEvent( event, alert_obj ) {
	
  var e = event || window.event;
	
  if( (e.keyCode == KEY_SPACE ) || 
      (e.keyCode == KEY_ESCAPE )  ||
      (e.keyCode == KEY_ENTER )  ){
      hideAlert( alert_obj );
  }  // endif
	
  return browser.stopPropagation(e);														
		
}

/**
 * handleAlertMouseClickEvent
 *
 * @param ( event object ) event
 *
 * @return nothing
 *
 */

 function handleAlertMouseClickEvent( event, alert_obj ) {
   var e = event || window.event;

   if( alert_obj.node_close == browser.target( e ) ) {
        hideAlert( alert_obj );
   }

   return browser.stopPropagation(e);														
	
 }


/**
 * handleAlertMouseDownEvent
 *
 * @param ( event object ) event
 *
 * @return nothing
 *
 */

 function handleAlertMouseDownEvent( event, alert_obj ) {
   var e = event || window.event;

   return browser.stopPropagation(e);														
	
 }

/**
 * handleAlertMouseMoveEvent
 *
 * @param ( event object ) event
 *
 * @return nothing
 *
 */

 function handleAlertMouseMoveEvent( event, alert_obj ) {
   var e = event || window.event;

   return browser.stopPropagation(e);														
	
 }


/**
 * handleAlertMouseUpEvent
 *
 * @param ( event object ) event
 *
 * @return nothing
 *
 */

 function handleAlertMouseUpEvent( event, alert_obj ) {
   var e = event || window.event;

   return browser.stopPropagation(e);														
	
 }


/**
 *
 * The checkGuess function checks the value of text box for a value between 1 and 10
 *
 * @contructor
 */

var MAX_NUM = 10;
var MIN_NUM = 1;

function Guess( text_id, check_id, again_id, box_id, alert ) {
 
   this.text_id = text_id;
   this.check_id = check_id;
   this.again_id = again_id;
   this.box_id = box_id;
   this.alert = alert;
   this.max_num = MAX_NUM;
   this.min_num = MIN_NUM;
   this.value = 1;
}

/**
 * init is a subclass of Guess 
 *  
 * @member Guess
 *
 * @return nothing
 */

Guess.prototype.init = function() {

  this.node_text  = document.getElementById(this.text_id);
  this.node_check = document.getElementById(this.check_id);
  this.node_again = document.getElementById(this.again_id);  
  this.node_box   = document.getElementById(this.box_id);  

  var obj1 = this;
  var obj2 = this.alert;

  newGuessValue( this );  

  this.alert.guess = obj1;  

  browser.addEvent(this.node_text, "keydown", function(event) {handleGuessKeyDownEvent(event, obj1, obj2 ); },   false);
  browser.addEvent(this.node_check, "click", function(event) {handleCheckGuessClickEvent(event, obj1, obj2); },   false);
  browser.addEvent(this.node_again, "click", function(event) {handlePlayAgainClickEvent(event,  obj1 ); },   false);

}

/**
 * newGuessValue is a subclass of Guess 
 *  
 * @member Guess
 *
 * @return nothing
 */

function newGuessValue( guess ) {

  guess.value = Math.floor(Math.random() * (guess.max_num.valueOf() - guess.min_num.valueOf() + 1) ) + guess.min_num.valueOf();
  guess.count = 0;
  guess.node_text.value = "";
  guess.node_text.setAttribute("aria-invalid", "false");

}


/**
 * handleGuessKeyDownEvent checks the guess and generates alert based on the guess
 *
 * @param ( event ) event is the event handler for the event
 * @param ( Guess object ) guess is the guesss object that is the target of the keyboard event
 *
 * @return false to stop event propagation if mouse event was used by handler, else true
 */

function handleGuessKeyDownEvent( event, guess, alert ) {
  var e = event || window.event;

  // Check to see if the value is valid

  if( isNaN( guess.node_text.value ) ||  
      (guess.node_text.value.valueOf() < guess.min_num.valueOf() ) || 
      (guess.node_text.value.valueOf() > guess.max_num.valueOf() )  ) {
      guess.node_text.setAttribute("aria-invalid", "true");
  } else {
      guess.node_text.setAttribute("aria-invalid", "false");
  }  // endif

  
  if( e.keyCode == KEY_ENTER )
    handleCheckGuessClickEvent( event, guess, alert );

}

/**
 * handleCheckGuessOnClick checks the guess and generates alert based on the guess
 *
 * @param ( event ) event is the event handler for the event
 * @param ( Guess object ) guess is the guesss object that is the target of the keyboard event
 *
 * @return false to stop event propagation if mouse event was used by handler, else true
 */

function handleCheckGuessClickEvent( event, guess, alert ) {
	
  guess.count++;

  var guess_value = new Number( guess.node_text.value );
  var target_value = new Number( guess.value );
  var guess_count = new Number( guess.count );

  
  if( guess.node_text.value == "" ) {
    showAlert( alert,  "You need to enter a value!" );
    return browser.stopPropagation( event );
  }

  if( isNaN( guess.node_text.value ) ) {
    showAlert( alert, "\"" + guess.node_text.value + "\" is not a number." );
    return browser.stopPropagation( event );
  }

  if( (guess_value.valueOf() < guess.min_num.valueOf() ) || (guess_value.valueOf() > guess.max_num.valueOf() )  ) {
    showAlert(alert, guess_value + " is not between " + guess.min_num + " and " + guess.max_num );
    return browser.stopPropagation( event );
  }

  if( guess_value.valueOf() == target_value.valueOf() ) {

    if( guess_count == 1 ) 
      showAlert( alert, guess_value + " is right, you got it on your first try!" );
    else	  
      showAlert( alert, guess_value + " is right, it only took you " + guess_count + " tries!" );

  } else {
	  
	 if( guess, guess_value.valueOf() < target_value.valueOf() ) {
		  
           showAlert(alert, guess_value + " is to low, try a higher number." );
		  
	 } else {
		  
           showAlert(alert, guess_value + " is to high, try a lower number." );
		  
	 } // endif
     	  
  } // endif
  
  return browser.stopPropagation( event );

}

/**
 * handlePlayAgainOnClick checks the guess and generates alert based on the guess
 *
 * @param ( event ) event is the event handler for the event
 * @param ( Guess object ) guess is the guesss object that is the target of the keyboard event
 *
 * @return false to stop event propagation if mouse event was used by handler, else true
 */

handlePlayAgainClickEvent = function( event, guess ) {
	
  newGuessValue( guess );
  guess.node_text.focus();
	
}





