var util = util || {};
window['util'] = util;


/**
 * Listens to the event of the element and uses callback for when the event
 * has fired.
 */
util.addEventListener = function(element, event, callback) {
	if (element.addEventListener) {
		element.addEventListener(event, callback, false);
	} else if (element.attachEvent) {
		element.attachEvent('on' + event, callback);
	}
};


/************* CONFIRMATIONS *************/
util.confirmDelete = function() {
	return confirm('Are you sure you want to delete?');
};

util.confirmBan = function() {
  return confirm('Are you sure you want to ban?');
};

util.confirmUpdate = function() {
  return confirm('This will override the values.\n' +
      'Are you sure you want to update?');
};

/**
 * Returns a random string.
 */
util.random = function() {
  return Math.abs(Math.floor(Math.random() * 2147483648) ^ 
      (new Date).getTime()).toString(36);
};


/************** ESCAPING ***************/

util.urlEncode = function(s) {
  return encodeURIComponent(s);
};

util.escapeHtml = function(s) {
  return s.replace(
    /[&<>"']/g,
    function(m) {
      var map = {
        "&": "amp",
        "<": "lt",
        ">": "gt",
        '"': "quot",
        "'": "#039"
      };

      return "&" + map[m] + ";";
    });
};

util.unescapeHtml = function(s) {
  return s.replace(
    /&(amp|[lg]t|quot|#\d{3});/g,
    function(m, p1) {
      var map = {
        amp:  "&",
        lt:   "<",
        gt:   ">",
        quot: '"',
        d039: "'"
      };
      return map[p1.replace(/#/g, 'd')];
    });
};


/**
 * Returns an XHR object. Browser safe.
 */
util.createXhr = function() {
  try {
    return new XMLHttpRequest(); // Firefox, Safari
  } catch(e) { 
    try { 
      return new ActiveXObject("Msxml2.XMLHTTP"); // IE
    } catch (e) { 
      try { 
        return new ActiveXObject("Microsoft.XMLHTTP"); // IE
      } catch (e) { 
        return null;
      } 
    } 
  }
};

/**
 * Calculates the absolute position (top, left) of the element.
 */
util.getAbsolutePosition = function(element) {
  var position = [0, 0];
  if (element.offsetParent) {
    do {
      position[0] += element.offsetTop;
      position[1] += element.offsetLeft;
      element = element.offsetParent;
    } while (element);
  }
  return position;
};

/**
 * Positions an element under another element.
 */
util.positionNearAnother = function(mainElement, otherElement, offset) {
  var position = util.getAbsolutePosition(mainElement);
  otherElement.style.position = 'absolute';
  otherElement.style.top = (position[0] + offset) + 'px';
  otherElement.style.left = position[1] + 'px';
};

/**
 * Returns verticall scroll position.
 */
util.getVerticalScroll = function() {
  var sy = 0;
  if (document.documentElement && document.documentElement.scrollTop) {
    sy = document.documentElement.scrollTop;
  } else if (document.body && document.body.scrollTop) {
    sy = document.body.scrollTop; 
  } else if (window.pageYOffset) {
    sy = window.pageYOffset;
  } else if (window.scrollY) {
    sy = window.scrollY;
  }
  return sy;
};

/************ NOTIFICATION ************/

/**
 * Displays notification message.
 */
util.notify = function(msg) {
  var note = document.getElementById('note');
  var noteText = document.getElementById('notetext');
  if (note && noteText) {
    noteText.innerHTML = msg;
    note.style.display = '';
    note.style.top = util.getVerticalScroll() + 'px';
    setTimeout('util.notify("' + msg + '")', 10);
  }
};

/************* SPINNER ***********/

util.spinnerFrame = 0;

/**
 * Draws the actual spinner.
 * @private
 */
util.drawSpinner_ = function(id) {
	var numSteps = 12;
	var spinner = document.getElementById(id)
  if (spinner && spinner.getContext) {
    var buffer = spinner.getContext('2d');
    
    buffer.save();
    buffer.fillStyle = 'rgb(255, 255, 255)';
    buffer.fillRect(0, 0, 20, 20);
    buffer.translate(10, 10);

    // Iterate through the steps.
    for (var j = 0; j < numSteps; j++) {
      var opacity = (numSteps - ((j + util.spinnerFrame) % numSteps)) / numSteps;

      buffer.rotate(-Math.PI * 2 / numSteps);
      buffer.beginPath();
      buffer.fillStyle = 'rgba(99, 99, 99, ' + opacity + ')';
      buffer.fillRect(-1, 4, 1.5, 6);
    }

    buffer.restore();
    util.spinnerFrame++;
  }
}

/**
 * Displays spinner and animates it.
 */
util.startSpinner = function(id) {
	var spinner = document.getElementById(id)
  if (spinner) {
    spinner.style.display = '';
    setInterval('util.drawSpinner_("' + id + '")', 80);
  }
}



/************** LIST OF CHECKBOXES ***************/

/**
 * Checks/unchecks all the checkboxes starting with a prefix to the same state
 * as the main "check all" checkbox.
 */
util.checkAll = function(formName, prefix) {
  var box = document.getElementById(prefix + 'CheckAllId');
  var boxes = document.forms[formName].elements;
  var boxLength = boxes.length;
  for (var i = 0; i < boxLength; i++) {
    if (boxes[i].type != 'checkbox' || boxes[i] == box || 
        boxes[i].name.indexOf(prefix) != 0) {
      continue;
    }
    boxes[i].checked = box.checked;
  }
};

/**
 * Handles checking on/off event by seeing the state of all checkboxes starting
 * with a prefix and setting the state of the main "check all" checkbox accordingly.
 */
util.check = function(formName, prefix) {
  var box = document.getElementById(prefix + 'CheckAllId');
  var boxes = document.forms[formName].elements;
  var boxLength = boxes.length;
  var allChecked = true;
  for (var i = 0; i < boxLength; i++) {
    if (boxes[i].type != 'checkbox' || boxes[i] == box || 
        boxes[i].name.indexOf(prefix) != 0) {
      continue;
    }
    if (!boxes[i].checked) {
      allChecked = false;
      break;
    }
  }
  box.checked = allChecked;
};


/**
 * Clears the field by id and optionally submits the form (if the 
 * form name is provided).
 */
util.clearField = function(id, formName) {
  var e = document.getElementById(id);
  if (e) {
    e.value = '';
    if (formName && document.forms[formName]) {
      document.forms[formName].submit();
    }
  }
};


/**
 * Toggles the display of the element.
 */
util.toggleDisplay = function(id) {
  var e = document.getElementById(id);
  if (e) {
    if (e.style.display == '') {
      e.style.display = 'none';
    } else {
      e.style.display = '';
    }
  }
};


/**
 * Disables elements after a slight delay.
 */
util.disable = function(arrayOfElements) {
  window.setTimeout(function() {
    for (var index in arrayOfElements) {
      var id = arrayOfElements[index];
      var e = document.getElementById(id);
      if (e) {
        e.disabled = true;
      }
    }
  }, 0);
};


/**
 * Calls the hide function if the event keypress has a keycode
 * corresponding to user trying to close the popup.
 */
util.popUpKeys = function(event, hide) {
  if (event.keyCode == 27 ||
      event.keyCode == 9 ||
      event.keyCode == 13) {
    hide();
    return false;
  }
  return true;
};



/************* CALENDAR *************/

util.calendar = null;


/**
 * Toggles active calendar, or opens a new one.
 */
util.toggleCalendar = function(element, event) {
  var e = document.getElementById('scwIframe');
  if (util.calendar != element.id ||
      e.style.visibility == 'hidden' ||
      e.style.display == 'none') {
    scwShow(element, event);
    util.calendar = element.id;
  } else {
    scwHide();
    util.calendar = null;
  }
};


/*************** SHOP **************/

util.changeShopStatus = function(s) {
  var r = '';
  if (s != 0) {
    r = prompt('You are about to decline a shop that was assigned to you. ' +
        'By declining you are less likely to be chosen for a future assignment. ' +
        'If you would still like to decline, please enter a reason:');
    if (!r || r.length == 0) {
      return false;
    }
  }

  var e = document.getElementById('streason');
  if (e) {
    e.value = r;
  }

  e = document.getElementById('st');
  if (e) {
    e.value = s;
  }
  return true;
}


