/*
  jQuery dropJ plugin
  Version 0.0.3 - Sat Feb 23 17:46:07 PST 2008
  @requires jQuery v1.2.3

  Documentation: http://code.google.com/p/jquery-dropj/
  Copyright (c) 2008 Ashley Pond V
  Licensed under the Artistic 2.0
  http://www.perlfoundation.org/artistic_license_2_0
*/

(function($) {
// http://unicode.org/versions/Unicode4.1.0/
//        CJK unified -> 4E00-9FFF
// Korean _syllables_ -> AC00-D7A3
//     Latin extended -> 00C0-02B8
var CJKrx = /^\s*([^\uAC00-\uD7A3\u4E00-\u9FFF]?[\u00C0-\u02B8\uAC00-\uD7A3\u4E00-\u9FFF])(.*)/im;
var ExtRx = /^\s*([^a-z\u00C0-\u02B8]?[a-z\u00C0-\u02B8])(.*)/im;
var ASCIIrx = /^\s*(\W?[a-z])(.*)/im;
var UnifiedRx = /^\s*([^a-z\u00C0-\u02B8\uAC00-\uD7A3\u4E00-\u9FFF]?[a-z\u00C0-\u02B8\uAC00-\uD7A3\u4E00-\u9FFF])(.*)/im;

var Mode = {
  "ascii":ASCIIrx
 ,"cjk":CJKrx
 ,"extended":ExtRx
 ,"unified":UnifiedRx
};

var dCSS = {
  /* opacity:0.7          // Big chars appear darker.
  ,padding:"0"
  ,display:"block"
  ,textAlign:"right"
  //,float:"left"         // Other text should flow around it.
  ,fontStyle:"normal"   // Italics would be bad here.
  ,fontWeight:"bold"    // Bold will be good.
  ,overflow:"visible"      // Bottom margin can clip.
//  ,textDecoration:"none!important" // When drop cap is a link. BREAKS IE 6*/
};

$.fn.dropJ = function(arg) {
    var opts = $.extend({}, $.fn.dropJ.defaults, arg);
    return this.each(function() {
      $this = $(this);
      var o = $.meta ? $.extend({}, opts, $this.data()) : opts;
      if ( _addDropCap($this.get(0),o) && o.clear )
      {
          $this.css({clear:"left"});
      }
    });
};

$.fn.dropJ.defaults = {
    "css":dCSS
   ,"clear":true
   ,"keepCase":true
   ,"regex":Mode.ascii
   ,"element":"span"
   ,"factor":3
   ,"toggleFamily":false
   ,"class":"dropj"
};

function _addDropCap(n,o) {
   var rx = Mode[o.mode] || Mode.ascii;
   if ( ( n.nodeType == 3 ) && n.nodeValue.match(rx) )
   {
      var val = n.nodeValue;
      val = val.replace(/\n+/g, " "); // stupid Rx is missing s flag.
      var capRemainder = val.match(rx);

      // this shuffle step courtesy of uneven Rx handling across browsers
      var capText = capRemainder ?
            capRemainder[ capRemainder.length - 2 ] : '';
      var remainderText = capRemainder ?
            capRemainder[ capRemainder.length - 1 ] : '';

      if ( ! o.keepCase ) capText = capText.toUpperCase();
      var cap = document.createTextNode(capText);
      var remainder = document.createTextNode(remainderText);
      var dropCap = document.createElement(o["element"]);
      dropCap.appendChild(cap);
      n.parentNode.replaceChild(remainder,n);
      remainder.parentNode.insertBefore(dropCap,remainder);
      $(dropCap).css(o["css"]);
      $(dropCap).addClass(o["class"]);
      _setSpecialCSS(dropCap,o)
      return dropCap;
   }
   else if ( n.nodeType == 3 )
   {
      $(n).parent().css({float:"left",display:"inline"});
   }
   for ( var i = 0; i < n.childNodes.length; i++ )
   {
      var dc = _addDropCap(n.childNodes[i],o);
      if ( dc ) return dc;
   }
};

function _setSpecialCSS(dc,o){
  var h = $(dc).css("lineHeight");
  if ( h.substr(h.length - 2, 2) == "px" ) // pixel mode
  {
     var px = h.substring(0,h.length - 2);
     var mt = ( -1 * Math.round( px / 10 ) ) + "px";
     var mb = ( -1 * Math.round( px / 5 ) ) + "px";
     $(dc).css({marginTop:mt,marginBottom:mb});
     var fs = ( o.factor * 1.05 * px ) + "px";
     var lh = ( o.factor * px * 0.98 ) + "px";
     $(dc).css({fontSize:fs,lineHeight:lh});
     if ( o.hang )
     {
       var w = ( o.factor * px * o.hang ) + "px";
       var m = ( -1 * ( o.factor * px * o.hang ) ) + "px";
       var mr = ( o.factor - 1 ) + "px";
       $(dc).css({marginLeft:m,marginRight:m,width:w,marginRight:mr});
     }
  }
  else // em mode
  {
     var fs = ( o.factor * 1.05 ) + "em";
     $(dc).css({fontSize:fs});
     $(dc).css({margin:"-.1ex 0 -.25ex 0",lineHeight:"95%"});
     if ( o.hang )
     {// IE 6 won't let px and em mix here
       var m = ( -1 * ( o.hang ) ) + "em";
       var mr = ( o.factor * .01 ) + "em";
       $(dc).css({marginLeft:m,width:"1em",marginRight:mr});
     }
  }
}
})(jQuery);


