/* ********************************************************************
 * Lightning BBCode - v0.2
 *   Copyright (c) 2009 - GreyWyvern
 *
 * Not licenced for distribution... yet
 *   All rights reserved
 *
 ******************************************************************* */
(function lightningBBCode() {
  var self = this;

  this.isIE = /*@cc_on!@*/false;
  this.imageDirectory = "/img/bbcode/";

  this.sizes = [7, 10, 12, 14, 18, 24, 32];
  this.colours = [
    ["Black", "Sienna", "DarkOliveGreen", "DarkGreen", "DarkSlateBlue", "Navy", "Indigo", "DarkSlateGray"],
    ["DarkRed", "DarkOrange", "Olive", "Green", "Teal", "Blue", "SlateGray", "DimGray"],
    ["Red", "SandyBrown", "YellowGreen", "SeaGreen", "MediumTurquoise", "RoyalBlue", "Purple", "Gray"],
    ["Magenta", "Orange", "Yellow", "Lime", "Cyan", "DeepSkyBlue", "DarkOrchid", "Silver"],
    ["Pink", "Wheat", "LemonChiffon", "PaleGreen", "PaleTurquoise", "LightBlue", "Plum", "White"]
  ];
  this.smileys = {
    'smile.png':     ':)',  'sad.png':       ':(',      'grin.png':      ':D',     'tongue.png':    ':P',
    'wink.png':      ';)',  'angry.png':     '>:(',     'cross.png':     ':X',     'crying.png':    ':\'(',
    'confused.png':  ':S',  'cool.png':      'B-)',     'shock.png':     ':O',     'neutral.png':   ':|',
    'angel.png':     'O:)', 'devil.png':     '>:)',     'thinking.png':  ':\\',    'sick.png':      ':sick:',
    'silent.png':    ':#',  'yawn.png':      ':yawn:',  'uhm-yeah.png':  ':?',     'shame.png':     ':blush:',
    'nerdy.png':     '8-)', 'dont-know.png': ':shrug:', 'hug-left.png':  ':hug{:', 'hug-right.png': ':}hug:',
    'kiss.png':      '(K)'
  };


  /* ******************************************************************
   * Build and return an individual toolbar button
   *
   */
  this.buildImage = function(src, alt, t1, t2, textarea) {
    var img = document.createElement('img');
        img.src = this.imageDirectory + src;
        img.textarea = textarea;
        img.tags = [t1, t2];
        img.alt = img.title = alt;
        img.onclick = function() { self.addCodes(this.tags[0], this.tags[1], this.textarea); };
    return img;
  }


  /* ******************************************************************
   * Show a subselection menu
   *
   */
  this.subSelect = function() {
    var _self = this;
    this.display = this.display || (this.nodeName != "TABLE" || !self.isIE) ? "table" : "block";
    if (this.rel.style.display != this.display) {
      setTimeout(function() {
        _self.rel.style.display = _self.display;
        _self.rel.style.top = (_self.parentNode.offsetHeight + 2) + "px";
        _self.rel.style.left = Math.min(_self.offsetLeft, _self.parentNode.offsetWidth - _self.rel.offsetWidth) + "px";
      }, 5);
    }
  };


  /* ******************************************************************
   * Add the specified codes at the selected insert point
   *
   */
  this.addCodes = function(t1, t2, textarea) {
    var url = "null", rng, sel, scr, loc, rep = "", dumb = document.selection;

    switch (t1) {
      case "[URL=#]": url = prompt('Enter the URL:', 'http://'); break;
      case "[IMG]": url = prompt('Enter the Image URL:', 'http://');
    } if (!url || url == "http://") return false;

    if (dumb) {
      textarea.focus();
      rng = document.selection.createRange();
      sel = rng.text.toString();
    } else {
      loc = [textarea.selectionStart, textarea.selectionEnd, textarea.value.length];
      scr = [textarea.scrollTop, textarea.scrollLeft];
      sel = textarea.value.substring(loc[0], loc[1]);
    }

    switch (t1) {
      case "[LIST]": case "[LIST=1]":
        for (var i = 0, list = sel.split('\n'); i < list.length; i++) list[i] = "[*]" + list[i];
        rep = '\n' + list.join("\n") + '\n';
        break;
      case "[URL=#]":
        rep = sel || url;
        t1 = t1.replace(/#/, url);
        break;
      case "[IMG]": rep = url; break;
      default: rep = sel;
    }

    if (dumb) {
      rng.text = t1 + rep + t2;
      rng.moveStart("character", -(rep.length + t2.length));
      rng.moveEnd("character", -t2.length);
      rng.select();
    } else {
      textarea.value =  textarea.value.substring(0, loc[0]) + t1 + rep + t2 + textarea.value.substring(loc[1], loc[2]);
      textarea.selectionStart = loc[0] + t1.length;
      textarea.selectionEnd = textarea.selectionStart + rep.length;
      textarea.scrollTop = scr[0];
      textarea.scrollLeft = scr[1];
    } textarea.focus();
  };


  /* ******************************************************************
   * Add the toolbar to all textareas with classname "bbcode"
   *
   */
  this.main = function() {
    var textareas = document.getElementsByTagName('textarea');
    for (var x = 0, elem; elem = textareas[x++];) {
      if (elem.className.indexOf('bbcode') > -1) {
        elem.toolbar = document.createElement('div');
        elem.toolbar.className = "lightningBBCodeToolbar";
        elem.toolbar.appendChild(document.createTextNode("BBCode: "));

        elem.toolbar.appendChild(this.buildImage("text_bold.png",           "Bold",            '[B]',      '[/B]',     elem));
        elem.toolbar.appendChild(this.buildImage("text_italic.png",         "Italic",          '[I]',      '[/I]',     elem));
        elem.toolbar.appendChild(this.buildImage("text_underline.png",      "Underline",       '[U]',      '[/U]',     elem));
        elem.toolbar.appendChild(this.buildImage("text_strikethrough.png",  "Strikethrough",   '[S]',      '[/S]',     elem));
        elem.toolbar.appendChild(this.buildImage("text_superscript.png",    "Superscript",     '[SUP]',    '[/SUP]',   elem));
        elem.toolbar.appendChild(this.buildImage("text_subscript.png",      "Subscript",       '[SUB]',    '[/SUB]',   elem));
        elem.toolbar.appendChild(this.buildImage("world_link.png",          "Link",            '[URL=#]',  '[/URL]',   elem));
        elem.toolbar.appendChild(this.buildImage("image.png",               "Image",           '[IMG]',    '[/IMG]',   elem));
        elem.toolbar.appendChild(this.buildImage("text_list_bullets.png",   "Unordered List",  '[LIST]',   '[/LIST]',  elem));
        elem.toolbar.appendChild(this.buildImage("text_list_numbers.png",   "Ordered List",    '[LIST=1]', '[/LIST]',  elem));
        elem.toolbar.appendChild(this.buildImage("comment.png",             "Quote",           '[QUOTE]',  '[/QUOTE]', elem));
        elem.toolbar.appendChild(this.buildImage("page_white_code.png",     "Code",            '[CODE]',   '[/CODE]',  elem));
        elem.toolbar.appendChild(this.buildImage("email_link.png",          "Email Link",      '[EMAIL]',  '[/EMAIL]', elem));
        elem.toolbar.appendChild(this.buildImage("text_horizontalrule.png", "Horizontal Rule", '[HR]',     '',         elem));

        // ***** Size *************************************************
        var sizetable = document.createElement('table');
            sizetable.cellSpacing = 2;
            sizetable.border = 0;
            sizetable.className = "lightningBBCodeToolbar_size";
            sizetable.textarea = elem;
            sizetable.tags = ["[SIZE=#]", "[/SIZE]"];
          var tbody = document.createElement('tbody');
            var tr = document.createElement('tr');
              for (var y = 0; y < this.sizes.length; y++) {
                var td = document.createElement('td');
                    td.style.fontSize = this.sizes[y] + "pt";
                    td.onclick = function() {
                      var table = this.parentNode.parentNode.parentNode;
                      self.addCodes(table.tags[0].replace(/#/, this.firstChild.nodeValue), table.tags[1], table.textarea);
                    };
                    td.appendChild(document.createTextNode(y + 1));
                  tr.appendChild(td);
              }
              tbody.appendChild(tr);
            sizetable.appendChild(tbody);
          elem.toolbar.appendChild(sizetable);

        var img = document.createElement('img');
            img.src = this.imageDirectory + "text_size.png";
            img.rel = sizetable;
            img.title = img.alt = "Font size";
            img.onclick = this.subSelect;
        elem.toolbar.appendChild(img);

        // ***** Colour ***********************************************
        var colourtable = document.createElement('table');
            colourtable.cellSpacing = 2;
            colourtable.border = 0;
            colourtable.className = "lightningBBCodeToolbar_color";
            colourtable.textarea = elem;
            colourtable.tags = ["[COLOR=#]", "[/COLOR]"];
          var tbody = document.createElement('tbody');
            for (var y = 0, row; row = this.colours[y++];) {
              var tr = document.createElement('tr');
                for (var z = 0, cell; cell = row[z++];) {
                  var td = document.createElement('td');
                      td.style.backgroundColor = td.title = cell;
                      td.appendChild(document.createTextNode(" "));
                      td.onclick = function() {
                        var table = this.parentNode.parentNode.parentNode;
                        self.addCodes(table.tags[0].replace(/#/, this.title), table.tags[1], table.textarea);
                      };
                    tr.appendChild(td);
                }
              tbody.appendChild(tr);
            }
            colourtable.appendChild(tbody);
        elem.toolbar.appendChild(colourtable);

        var img = document.createElement('img');
            img.src = this.imageDirectory + "color_swatch.png";
            img.rel = colourtable;
            img.title = img.alt = "Font colour";
            img.onclick = this.subSelect;
        elem.toolbar.appendChild(img);

        // ***** Smileys **********************************************
        var smileydiv = document.createElement('div');
            smileydiv.className = "lightningBBCodeToolbar_smileys";
            smileydiv.textarea = elem;
          var y = 0;
          for (sm in this.smileys) {
            var img = document.createElement('img');
                img.width = img.height = 16;
                img.src = this.imageDirectory + "smileys/" + sm;
                img.tag = img.alt = img.title = this.smileys[sm];
                img.onclick = function() { self.addCodes(this.tag, '', this.parentNode.textarea); };
              smileydiv.appendChild(img);
            if (y++ && !(y %= 5)) smileydiv.appendChild(document.createElement('br'));
          }
        elem.toolbar.appendChild(smileydiv);

        var img = document.createElement('img');
            img.src = this.imageDirectory + "smileys/smile.png";
            img.rel = smileydiv;
            img.title = img.alt = "Smileys";
            img.onclick = this.subSelect;
        elem.toolbar.appendChild(img);

        // ***** Hide popups on document click ************************
        var hidePopups = (function(items) { return function() {
          for (var x = 0, i; i = items[x++];)
            if (i.style.display != "none") i.style.display = "none";
        }})([sizetable, colourtable, smileydiv]);
        if (window.addEventListener) {
          document.documentElement.addEventListener('click', hidePopups, false); 
        } else if (window.attachEvent)
          document.documentElement.attachEvent('onclick', hidePopups);

        // ***** Insert the toolbar ***********************************
        elem.parentNode.insertBefore(elem.toolbar, elem);

        // ***** Keyboard shortcuts ***********************************
        elem.onkeyup = function(e) {
          e = e || event;
          if (e.ctrlKey) {
            var buttons = this.toolbar.getElementsByTagName('img');
            switch (e.keyCode) {
              case 66: buttons[0].onclick(); return false; // Ctrl + B = Bold
              case 73: buttons[1].onclick(); return false; // Ctrl + I = Italic
              case 85: buttons[2].onclick(); return false; // Ctrl + U = Underline
              default: // alert(e.keyCode);
            }
          } return true;
        };
        elem.onkeydown = elem.onkeypress = function(e) {
          e = e || event;
          switch (e.keyCode) {
            case 66: case 73: case 85: return !e.ctrlKey;
            default: return true;
          }
        };
      }
    }
  };

  if (window.addEventListener) {
    window.addEventListener('load', this.main, false); 
  } else if (window.attachEvent)
    window.attachEvent('onload', this.main);
})();