// IP.Board: 'Fast Reply' Improvements
// Copyright (c) 2006-2007 Orbona
// Version 1.0
// Release Date: 2007-10-22
//
// See also: http://www.orbona.com/greasemonkey/
//
// Original file name: ipboard_fastreply.user.js
// Please reference the original file name when contacting me regarding this
// script.
//
// This software is licensed under the CC-GNU GPL:
// http://creativecommons.org/license/cc-gpl
//
//---------------------------------------------------------------------------
// DESCRIPTION
//
// This script was created for use on Invision Power Boards (IP.Board, see
// http://www.invisionpower.com).
//
// (1) Adds a Fast Reply button at the top of the page which behaves just
//     like the Fast Reply button at the bottom of the page.
//
// (2) When any action is taken that opens the "Fast Reply" form, the focus
//     is automatically moved to the "fast reply" text area so that typing
//     can begin immediately.
//
// (3) Adds shortcuts for formatting text to the reply text area. CTRL-B
//     will add bold tags, CTRL-I will add italic tags, and CTRL-Q will add
//     "Quote" tags to the selected text.Not all IP.Boards support all
//     formatting options.
//
// (4) Adds shortcuts for inserting (my) commonly used phrases. CTRL-SHIFT-G
//     appends an italicized 'Edited for grammar' to the post. CTRL-SHIFT-C
//     appends an italicized 'Edited for clarification' to the post.
//     CTRL-SHIFT-I inserts an "In my opinion,". CTRL-SHIFT-T appends a
//     "Thanks in advance." to the post,
// --------------------------------------------------------------------------

// ==UserScript==
// @name            IP.Board: 'Fast Reply' Improvements
// @description     Adds a 'Fast Reply' button to the top of the page, moves focus to the fast reply text area when it is opened, and adds shortcuts (CTRL-B, CTRL-I, CTRL-Q) for formatting selected text and inserting commonly used phrases
// @namespace       http://www.orbona.com/greasemonkey/
// @include         http://forums.televisionwithoutpity.com/index.php?showtopic*
// @include         http://www2.konfabulator.com/forums/index.php?showtopic*
// ==/UserScript==

//-----------------------------------------------------------------------------
// Stops the default event action from occuring.
//-----------------------------------------------------------------------------
function stopDefault(event) {
   event.preventDefault();
   event.stopPropogation();
}

//-----------------------------------------------------------------------------
// Shows or hides the fast reply area, and sets the focus to the fast reply
// area if it is showing
//-----------------------------------------------------------------------------
function focusFastReply(event) {
   //unsafeWindow.ShowHide('qr_open','qr_closed');
   //to avoid using unsafeWindow
   toggleView ('qr_open');
   toggleView('qr_closed');

   var fastReplyArea = document.getElementById('fastreplyarea');

   if (fastReplyArea.style.display != 'none') fastReplyArea.focus();
   //stopDefault(event);
}

//-----------------------------------------------------------------------------
// Show/hide element specified by id
//-----------------------------------------------------------------------------

function toggleView(id) {
   if ( !id ) return;
   var itm = document.getElementById(id);

   if ( itm )
      itm.style.display = itm.style.display=="none" ? "" : "none";

}
//-----------------------------------------------------------------------------
// Surrounds the selected text with the appropriate UBB tags, or inserts the
// appropriate text.
//-----------------------------------------------------------------------------
function handleKey(event) {
   var target = event ? event.target : this;
   var key, selStart, selEnd, stringKey, tag;

   if (event.shiftKey && event.ctrlKey) {
     key = event.which || event.charCode || event.keyCode;

     switch (key) {
         case 67:  //C
            target.value = target.value + '\n\n' + '[i]Edited for clarification.[/i]';
            stopDefault(event);
            break;
         case 71: //G
            target.value = target.value + '\n\n' + '[i]Edited for grammar.[/i]';
            stopDefault(event);
            break;
         case 73: //I
            selStart = target.selectionStart;
            selEnd = target.selectionEnd;

            target.value = target.value.substring(0, selStart) + 'In my opinion, ' + target.value.substring(selEnd, target.value.length);
            stopDefault(event);
            break;
         case 84: //T
            selStart = target.selectionStart;
            selEnd = target.selectionEnd;

            target.value = target.value + 'Thanks in advance.';
            stopDefault(event);
      }
   }
   else if (event.ctrlKey) {
      key = event.which || event.charCode || event.keyCode;
      stringKey = String.fromCharCode(key).toUpperCase();

      if (stringKey=="B" || stringKey=="I" || stringKey=="Q") {
         tag= stringKey!="Q" ? stringKey : "QUOTE";

         selStart = target.selectionStart;
         selEnd = target.selectionEnd;

         target.value = target.value.substring(0, selStart)+ '[' + tag + ']' + target.value.substring(selStart, selEnd) + '[/' + tag + ']'+ target.value.substring(selEnd, target.value.length);

         stopDefault(event);
      }
   }
}

// ----------------------------------------------------------------------------
// Changes the id attribute of a node to include a "-clone" at the end. If the
// node doesn't have an id attribute, it is not added.  Currently used to
// ensure cloned nodes have unique ids when added to the document.
// ----------------------------------------------------------------------------
function changeId(node) {
   var children, i;

   if(node.nodeType == 1 && node.id)
      node.id += '-clone';

   children = node.childNodes;

   for(i = 0;i < children.length;i++)
      changeId(children.item(i));
}

// ----------------------------------------------------------------------------
// Main function that does everything described in the description area above.
// ----------------------------------------------------------------------------
function doIt() {
   var fastReplyArea =  document.getElementById('fastreplyarea');
   var links, currentLink, clonedFastReply;

   if (fastReplyArea) {
      //Adds shortcut keys for text formatting
      fastReplyArea.addEventListener('keypress', handleKey, true);

      // Modifies any "Fast Reply" buttons to transfer focus to the fast reply area text box.
      links=document.evaluate("//A[contains(@href,'qr_open')]", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,  null);
      for (var i = 0; i < links.snapshotLength; i++) {
         currentLink = links.snapshotItem(i);
         currentLink .addEventListener('click', focusFastReply, true);
         currentLink.addEventListener('click', function(event) {stopDefault(event);}, false);

         clonedNode = currentLink.cloneNode(true);
         clonedNode.addEventListener('click', focusFastReply, true);
         clonedNode.addEventListener('click', function(event) {stopDefault(event);}, false);
         changeId(clonedNode);
      }

      //Add "Fast Reply" button at top, in front of non-fast "Reply"
      links=document.evaluate("//A[contains(@href,'reply_post')]", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,  null);

      if (links.snapshotLength > 0 && clonedNode)
         links.snapshotItem(0).parentNode.insertBefore(clonedNode, links.snapshotItem(0));
   }
}

// ------------------END OF FUNCTIONS -----------------------------

window.addEventListener("load", function() { doIt(); }, false);

