// UBB: Post Saver and Formatter
// Copyright (c) 2006-2007 Orbona
// Version 1.0
// Release Date: 2007-10-22
//
// See also: http://www.orbona.com/greasemonkey/
//
// Original file name: ubb_postsaveformat.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 sites that use UBB.
//
// This script adds shortcuts for formatting text to the post 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.
//
// This script also 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.
//
// This script modifies the page so that posts are automatically copied to
// the system clipboard or to Greasemonkey storage when a post is submitted.
// Since the "copy" is performed before the page unloads, posts will never
// be lost again (well, unless changes to the site or to Greasemonkey break
// this script).  This is quite handy, because on some message boards,
// returning to the "add/edit post form" doesn't always show you a cached
// version of what was typed.  When this script is used, if a "submit"
// doesn't complete properly, a "Paste" or Tools >> Greasemonkey >>
// User Script Commands will give you back your post.
//
// WARNING: (1) When you submit a post, any text already on the system
// clipboard will be overwritten.
//
// (2) Obviously, a subsequent "cut" or "copy" will overwrite the
// post data on the system clipboard, so it's a good idea to
// see if your post got "eaten" before doing any more text
// editing in any application.
//-----------------------------------------------------------------------------

// ==UserScript==
// @name UBB: Post Saver and Formatter
// @description Automatically copies posts when submitting 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://www.coolrunning.com/cgi-bin/ubb/postings.cgi*
// ==/UserScript==

var postContentName="";

//-----------------------------------------------------------------------------
// A wrapper for the main "copyPostToClipboard" method added to the main
// document. Exists so we can use it in "addEventListener" and method
// redefinitions
//-----------------------------------------------------------------------------
function copyPostToClipboardWrapper (event) {

   if (GM_getValue('useclip', "2")=="1")
      unsafeWindow.copyPostToClipboard();
   else {
      var postContentElem =  document.getElementsByName(postContentName);

      if (postContentElem.length > 0) GM_setValue('posttext', postContentElem[0].value);
   }
   this._submit();   // call real submit function
}

//-----------------------------------------------------------------------------
// Retrieves the post from Greasmonkey storage. If the user is currently
// saving to the system clipboard, then the most recently edited post won't
// be here. Selecting 'ok' on the prompt window will paste the last post
// contents into the post body text box.
//-----------------------------------------------------------------------------
function retrievePost(e) {
   var lastPost=GM_getValue('posttext', "");
   var ans = prompt('Here is your last saved post:', lastPost.replace(/\n/g,'\\n'));

   if (ans) {
      var postContentElem =  document.getElementsByName(postContentName);
      if (postContentElem) {
         postContentElem.value += lastPost;
         postContentElem.focus();
      }
   }
}

//-----------------------------------------------------------------------------
// Prompts for save location for the post text and sets the post to be saved
// to the clipboard or a Greasemonkey configuration variable.
//-----------------------------------------------------------------------------
function enterSaveLocation (e) {
   var saveToClipboard = GM_getValue('useclip', "2")=="1";

   var msg = "Your posts are currently saved to ";
   msg += saveToClipboard ? "the system clipboard.\n\n" : "Greasemonkey storage.\n\n";
   msg += "To save to the system clipboard, which requires special configuration, enter a \"1\".\nTo save to Greasemonkey storage, enter a \"2\".";

   var reply = prompt(msg, saveToClipboard  ? "1" : "2");
   if (!reply) return;

   if (reply != "2" && reply !="1")
      alert ("You have entered an invalid choice.  Save location has not been changed.");
   else
      GM_setValue('useclip', reply);
}

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

//-----------------------------------------------------------------------------
// 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);
      }
   }
}

// ----------------------------------------------------------------------------
// Main function that does everything described in the description area above.
// ----------------------------------------------------------------------------
function doIt() {
   GM_registerMenuCommand('UBB: Set post save location ...',  enterSaveLocation, "l", "shift alt", "l");
   GM_registerMenuCommand('UBB: Retrieve post data from Greasemonkey storage',  retrievePost, "r", "shift alt", "r");

   var postContentElem, script;
   var submitForm = document.getElementsByName('REPLIER');

   if (!submitForm || submitForm.length===0) {
      submitForm = document.getElementsByName('PostTopic');
      if (submitForm && submitForm[0])
         postContentElem = document.getElementsByName('Message');
   }
   else {
      postContentElem = document.getElementsByName('ReplyMessage');

      if (!postContentElem || postContentElem.length===0)
      postContentElem = document.getElementsByName('EditedMessage');
   }

   if (postContentElem && postContentElem[0]) {
      submitForm = submitForm[0];
      postContentElem=postContentElem[0];
      postContentName = postContentElem.name;
      postContentElem.addEventListener('keypress', handleKey, true);

      // Greasemonkey doesn't recognize the "netscape" (used below) and GM
      // doesn't currently provide access to the  system clipboard. So, I'm
      // forced to add  this javascript to the main document and call it
      // via my wrapper see below). Will modify in the future if a better
      // way presents itself.
      // see also: http://www.febooti.com/support/website-help/website-javascript-copy-clipboard.html
      // see also: http://developer.mozilla.org/en/docs/Using_the_Clipboard
      // see also: http://www.xulplanet.com/tutorials/mozsdk/clipboard.php
      script = document.createElement('script');
      script.type = 'text/javascript';
      script.innerHTML = 'function copyPostToClipboard() { var copytext=document.' + submitForm.name + '.' + postContentName + '.value;var clipboard, transferable,clipboardID, str; try{ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); } catch(e){ alert(e); } try{ clipboard=Components.classes["@mozilla.org/widget/clipboard;1"].createInstance(Components.interfaces.nsIClipboard); }catch(e){ alert(e); } try{ transferable=Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable); }catch(e){ alert(e); } transferable.addDataFlavor("text/unicode"); str=Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString); str.data=copytext; transferable.setTransferData("text/unicode",str,str.data.length*2); try{ clipboardID=Components.interfaces.nsIClipboard; } catch(e){ alert(e); } clipboard.setData(transferable,null,clipboardID.kGlobalClipboard); }';
      document.body.appendChild(script);

   }
 }

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

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

//capture any post text for any submitted forms, because I really hate losing
//what I typed
window.addEventListener('submit', copyPostToClipboardWrapper, true);

// If a script calls someForm.submit(), the onsubmit event does not fire,
// so we need to redefine the submit method of the HTMLFormElement class
// and we want to copy that post no matter how it is submitted
HTMLFormElement.prototype._submit = HTMLFormElement.prototype.submit;
HTMLFormElement.prototype.submit = copyPostToClipboardWrapper;
