/** -------------------------------------------------------
 * Author: Chris Wetherell at Google, based on code by Chris
 * Wetherell before Google.
 *
 * Textbar() [object]
 *
 * A class that can take the currently selected (highlighted)
 * text and wrap it in HTML tags commonly used for formatting.
 *
 * TODO: This could be generalized for, say, template use(!)
 *
 * Based on code found at massless.org.  Which, given that *I* am
 * that site's author makes this credit declaration intentionally
 * confusing.
 *
 * Warning: Expects presence of dom.common.js and detect.js.
 *
 * Typical usage:
 * On an HTML element: onclick="Textbar.Bold();"
  ------------------------------------------------------- */

function Textbar() {}

Textbar.ELEMENT_ID;
Textbar.PREVIEW_BUTTON;

/* -----------
 * Format tags
 * ----------- */

Textbar.Bold = function(elmid)
{
  this.wrapSelection('<strong>','</strong>');
}

Textbar.Italic = function()
{
  this.wrapSelection('<i>','</i>');
}

Textbar.H1 = function()
{
  this.wrapSelection("<h1>","</h1>");
}

Textbar.List = function()
{
  this.wrapSelection("<ul>","</ul>");
}

Textbar.ListOrdered = function()
{
  this.wrapSelection("<ol>","</ol>");
}

Textbar.ListItem = function()
{
  this.wrapSelection("<li>","</li>");
}

Textbar.Link = function()
{
  this.wrapSelectionWithLink(this.getElement());
}

Textbar.Mail = function()
{
  this.wrapSelectionWithMailTo(this.getElement());
}

/**
 * getElement()
 *
 * For storing the element (usually a <textarea>) where the
 * text will be modified.
 */
Textbar.Element = false;
Textbar.getElement = function()
{
  if (!this.Element) {
     this.Element = d(this.ELEMENT_ID);
  }
  return this.Element;
}



/**
 * wrapSelection()
 *
 * Branches out the tag wrapping code for differing implementations
 * of selection management. *sigh*  Standards, where art thou?
 */
Textbar.wrapSelection = function(lft, rgt) {

  Textbar.Element = false;
  if (Detect.IE() && ! Detect.SAFARI() ) {
    this.IEWrap(lft, rgt);
  } else if (DOM) {
    this.mozWrap(lft, rgt);
    alert
  }
}



/**
 * wrapSelectionWithLink()
 *
 * Wrap a hyperlink around some text by prompting the user for
 * a URL.
 */
Textbar.wrapSelectionWithLink = function() {
  var my_link = prompt("Enter URL:","http://");
  if (my_link != null) {
    lft="<a href=\"" + my_link + "\"";
    if (my_link.indexOf(location.host) == -1) {
        lft+=" target=\"_blank\"";
    }
    lft+=">";
    rgt="</a>";
    this.wrapSelection(lft, rgt);
  }
  return;
}

/**
 * wrapSelectionWithMailTo()
 *
 * Wrap a mailto hyperlink around some text by prompting the user for
 * a URL.
 */
Textbar.wrapSelectionWithMailTo = function() {
  var my_mail = prompt("Enter Mail Address:","mailto:");
  if (my_mail != null) {
    lft="<a href=\"" + my_mail + "\">";
    rgt="</a>";
    this.wrapSelection(lft, rgt);
  }
  return;
}

/**
 * mozWrap()
 *
 * Wraps tags around text in Mozilla/Gecko browsers.
 */
Textbar.mozWrap = function(lft, rgt) {

  var txtarea=this.getElement();
  var v = txtarea.value;
  var selLength = txtarea.textLength;
  var selStart = txtarea.selectionStart;
  var selEnd = txtarea.selectionEnd;
  if (selEnd==1 || selEnd==2) selEnd=selLength;
  var s1 = (v).substring(0,selStart);
  var s2 = (v).substring(selStart, selEnd)
  var s3 = (v).substring(selEnd, selLength);
  txtarea.value = s1 + lft + s2 + rgt + s3;

}



/**
 * IEWrap()
 *
 * Wraps tags around text in Internet Explorer.
 */
Textbar.IEWrap = function(lft, rgt) {

  txtarea=this.getElement();
  strSelection = document.selection.createRange().text;

  if (strSelection!="")
  {
    document.selection.createRange().text = lft + strSelection + rgt;
  } else {
    txtarea.focus()
    strSelection = document.selection.createRange().text;
    txtarea.value = txtarea.value + lft + rgt;
  }

}

// Emulate the 'click' function in IE for Mozilla
// TODO: Add to cross-browser event library
if (Detect.MOZILLA()) {
  HTMLElement.prototype.click = function () {
    if (typeof this.onclick == 'function')
      this.onclick({type: 'click'});
  };
}



/**
 * isCtrlShiftKeyPressed()
 *
 * Determine by char index whether a certain key's been pressed in conjunction
 * with the CTRL and SHIFT keys.
 */
function isKeyPressedWithCtrlShift(num, e) {
  key = getKeyAfterCtrlAndShift(e);
  if (key) return (key == num);
  return false;
}



/**
 * activateKeyCommands()
 *
 * Based on a combination of keystrokes and keyholds, activate
 * a particular formatting method.
 *
 * Warning: In Safari, only the Preview button onclick command works
 * since there is no selection management yet for that browser.
 */
Textbar.activateKeyCommands = function(e) {

  IE_KEYSET = (Detect.IE() || Detect.SAFARI());

  CTRL_SHFT_A = (IE_KEYSET) ?
    isKeyPressedWithCtrlShift(1, e) : isKeyPressedWithCtrlShift(65, e);

  CTRL_SHFT_B = (IE_KEYSET) ?
    isKeyPressedWithCtrlShift(2, e) : isKeyPressedWithCtrlShift(66, e);

  CTRL_SHFT_T = (IE_KEYSET) ?
    isKeyPressedWithCtrlShift(20, e) : isKeyPressedWithCtrlShift(84, e);

  CTRL_SHFT_L = (IE_KEYSET) ?
    isKeyPressedWithCtrlShift(12, e) : isKeyPressedWithCtrlShift(76, e);

  CTRL_SHFT_P = (IE_KEYSET) ?
    isKeyPressedWithCtrlShift(16, e) : isKeyPressedWithCtrlShift(80, e);

  CTRL_SHFT_S = (IE_KEYSET) ?
    isKeyPressedWithCtrlShift(19, e) : isKeyPressedWithCtrlShift(83, e);

  CTRL_SHFT_D = (IE_KEYSET) ?
    isKeyPressedWithCtrlShift(4, e) : isKeyPressedWithCtrlShift(68, e);


  if (CTRL_SHFT_P) d(Textbar.PREVIEW_BUTTON).onclick();
  if (CTRL_SHFT_S) d(Posting.PUBLISH_BUTTON).click();
  if (CTRL_SHFT_D) d(Posting.DRAFT_BUTTON).click();

  // WARNING: The following can delete data in a textarea in Safari as of
  // 1.2.1 (v125.1)
  if (!Detect.SAFARI()) {
    if (CTRL_SHFT_A) Textbar.Link();
    if (CTRL_SHFT_B) Textbar.Bold();
    if (CTRL_SHFT_T) Textbar.Italic();
    if (CTRL_SHFT_L) Textbar.Blockquote();
  }

  return true;
}


// The following functions help manage some differing browser event models and
// key detection.
function getKeyAfterCtrl(e) {
  if (isCtrlKeyPressed(e)) { return getKey(e); }
  return false;
}

function getKeyAfterCtrlAndShift(e) {
  if (isCtrlKeyPressed(e) && isShiftKeyPressed(e)) { return getKey(e); }
  return false;
}

function isCtrlKeyPressed(e) {
  return getEvent(e).ctrlKey;
}

function isShiftKeyPressed(e) {
  return getEvent(e).shiftKey;
}

function getKey(e) {
  key = getEvent(e).keyCode;
  if (!key) key = getEvent(e).charCode;
  return key;
}

function getEvent(e) {
  return (!e) ? event : e;
}

// set listener
document.onkeypress = Textbar.activateKeyCommands;



