/**
 * jQuery wrShadow-plugin (jquery.wrshadow.js)
 *
 * Modifies object(s), adds PNG-based shadow around object
 *
 * CSS for shadow is required, can be modified for best result
 * Paths to images is specified in CSS
 *
 * @version 0.1
 * @Created: 2010-11-02
 * @Author: Oscar Engström, www.engstream.se
 *
 */
(function($) {
  $.fn.wrShadow = function(options) {
      var opts = $.extend({}, $.fn.wrShadow.defaults, options);

      //Is this a webkit-browser? (like Safari or Chrome)
      if($.browser.webkit){
          //Yes it is, then we need to wait until document is loaded, otherwise it will look messy
          $tmp = this; //Otherwise it won't be recognized in window load-function
          $(window).load(function(){
              return $.fn.wrShadow.logic($tmp);
          });
      } else {
          //No, that's good, just continue
          return $.fn.wrShadow.logic(this);
      }
  };

  $.fn.wrShadow.logic = function(object){
      return object.each(function() {
         $this = $(this);

         if($this.hasClass('wrShadowMini')){
           $.fn.wrShadow.params.isMini = 1;
           $.fn.wrShadow.params.cornerWidth = $.fn.wrShadow.defaults.miniCornerWidth;
           $.fn.wrShadow.params.shadowWidth = $.fn.wrShadow.defaults.miniShadowWidth;
         } else {
           $.fn.wrShadow.params.isMini = 0;
           $.fn.wrShadow.params.cornerWidth = $.fn.wrShadow.defaults.cornerWidth;
           $.fn.wrShadow.params.shadowWidth = $.fn.wrShadow.defaults.shadowWidth;
         }

         //Measurement, this is needed for setting individual widths and heights for objects shadow
         objectWidth = $this.width();
         objectHeight = $this.height();
         borderRightWidth = parseInt($this.css("borderRightWidth"), 10);
         if(isNaN(borderRightWidth)){
           borderRightWidth = parseInt(1);
         }
         borderLeftWidth = parseInt($this.css("borderLeftWidth"), 10);
         if(isNaN(borderLeftWidth)){
           borderLeftWidth = parseInt(1);
         }
         borderTopWidth = parseInt($this.css("borderTopWidth"), 10);
         if(isNaN(borderTopWidth)){
           borderTopWidth = parseInt(1);
         }
         borderBottomWidth = parseInt($this.css("borderBottomWidth"), 10);
         if(isNaN(borderBottomWidth)){
           borderBottomWidth = parseInt(1);
         }
         borderWidth = borderRightWidth + borderLeftWidth;
         borderHeight = borderTopWidth + borderBottomWidth;
        //alert(borderHeight + ' ' + borderWidth);
         //Get padding for element
         tmpPadding = new Array();
         tmpPadding['top'] = $this.css('paddingTop');
         tmpPadding['right'] = $this.css('paddingRight');
         tmpPadding['bottom'] = $this.css('paddingBottom');
         tmpPadding['left'] = $this.css('paddingLeft');
         horizontalWidth = (objectWidth + 2*($.fn.wrShadow.params.shadowWidth)) - 2*($.fn.wrShadow.params.cornerWidth) + borderWidth;
         //alert(horizontalWidth + ', ' + borderWidth);
         horizontalWidth += parseInt(tmpPadding['right'], 10) + parseInt(tmpPadding['left'], 10);
         //alert(horizontalWidth + ', ' + tmpPadding['left'] + ', ' + parseInt(tmpPadding['left'], 10));

         //Get margins for image, then remove them from image, we will add the values again later on for shadowWrapper
         tmpMargin = new Array();
         tmpMargin['top'] = $this.css('marginTop');
         tmpMargin['right'] = $this.css('marginRight');
         tmpMargin['bottom'] = $this.css('marginBottom');
         tmpMargin['left'] = $this.css('marginLeft');
         //Remove margins from image
         $this.css('margin', 0);

         tmpObject = $('<span>');
         tmpObject.addClass('shadowWrapper');
         if($.fn.wrShadow.params.isMini){
           tmpObject.addClass('mini');
         }
         if($this.hasClass('floatLeft')){
             tmpObject.addClass('floatLeft');
         } else if($this.hasClass('floatRight')){
             tmpObject.addClass('floatRight');
         }
         tmpObject.css({
             'width' : objectWidth + 2*($.fn.wrShadow.params.shadowWidth) + borderWidth + parseInt(tmpPadding['right'], 10) + parseInt(tmpPadding['left'], 10) + 'px'
         });

         //Add margin from image
         tmpObject.css('marginTop', tmpMargin['top']);
         tmpObject.css('marginRight', tmpMargin['right']);
         tmpObject.css('marginBottom', tmpMargin['bottom']);
         tmpObject.css('marginLeft', tmpMargin['left']);

         if($this.parent('.shadowWrapper').length > 0){
           //This element has already been wrapped, don't wrap it again
           $.fn.wrShadow.adjustMeasurements($this);
         } else {
           //This element hasn't been wrapped yet, do it
           $this.wrap(tmpObject);

           tmpObject.addClass('shadowWrapper');
           if($.fn.wrShadow.params.isMini){
             tmpObject.addClass('mini');
           }
           if($this.hasClass('floatLeft')){
               tmpObject.addClass('floatLeft');
           } else if($this.hasClass('floatRight')){
               tmpObject.addClass('floatRight');
           }
           tmpObject.css({
               'width' : objectWidth + 2*($.fn.wrShadow.params.shadowWidth) + borderWidth + parseInt(tmpPadding['right'], 10) + parseInt(tmpPadding['left'], 10) + 'px'
           });

           //Add margin from image
           tmpObject.css('marginTop', tmpMargin['top']);
           tmpObject.css('marginRight', tmpMargin['right']);
           tmpObject.css('marginBottom', tmpMargin['bottom']);
           tmpObject.css('marginLeft', tmpMargin['left']);

           $this.before($.fn.wrShadow.prependMarkup());
           $this.after($.fn.wrShadow.appendMarkup());

           //Run render() for updating headlines
           render();

           //Bind it, when resized update shadowwidth/height
           $(this).resize(function(){
             $.fn.wrShadow.adjustMeasurements($(this));
           });
         }

     });
  }

  $.fn.wrShadow.prependMarkup = function(){
      tmpContainer = $('<div>');

      tmpObject = $('<span>');
      tmpObject.addClass('shadowTopLeft');
      tmpContainer.append(tmpObject);
      tmpObject = $('<span>');
      tmpObject.addClass('shadowTopMiddle');
      tmpObject.css({
          'width' : horizontalWidth + 'px'
      });
      tmpContainer.append(tmpObject);
      tmpObject = $('<span>');
      tmpObject.addClass('shadowTopRight');
      tmpContainer.append(tmpObject);
      tmpObject = $('<span>');
      tmpObject.addClass('shadowLeft');
      tmpObject.css({
          'height' : objectHeight + borderHeight + parseInt(tmpPadding['top'], 10) + parseInt(tmpPadding['bottom'], 10) + 'px'
      });
      tmpContainer.append(tmpObject);
      
      return tmpContainer.html();
  };

  $.fn.wrShadow.appendMarkup = function(){
      tmpContainer = $('<div>');

      tmpObject = $('<span>');
      tmpObject.addClass('shadowRight');
      tmpObject.css({
          'height' : objectHeight + borderHeight + parseInt(tmpPadding['top'], 10) + parseInt(tmpPadding['bottom'], 10) + 'px'
      });
      tmpContainer.append(tmpObject);
      tmpObject = $('<span>');
      tmpObject.addClass('shadowBottomLeft');
      tmpContainer.append(tmpObject);
      tmpObject = $('<span>');
      tmpObject.addClass('shadowBottomMiddle');
      tmpObject.css({
          'width' : horizontalWidth + 'px'
      });
      tmpContainer.append(tmpObject);
      tmpObject = $('<span>');
      tmpObject.addClass('shadowBottomRight');
      tmpContainer.append(tmpObject);

      return tmpContainer.html();
  };

  $.fn.wrShadow.adjustMeasurements = function($element){
    //$wrapper = $element.parents('.shadowWrapper');
    if($this.hasClass('wrShadowMini')){
      $.fn.wrShadow.params.isMini = 1;
      $.fn.wrShadow.params.cornerWidth = $.fn.wrShadow.defaults.miniCornerWidth;
      $.fn.wrShadow.params.shadowWidth = $.fn.wrShadow.defaults.miniShadowWidth;
    } else {
      $.fn.wrShadow.params.isMini = 0;
      $.fn.wrShadow.params.cornerWidth = $.fn.wrShadow.defaults.cornerWidth;
      $.fn.wrShadow.params.shadowWidth = $.fn.wrShadow.defaults.shadowWidth;
    }

    objectWidth = $element.width();
    objectHeight = $element.height();
    borderWidth = parseInt($this.css("borderLeftWidth"), 10) + parseInt($this.css("borderRightWidth"), 10);
    borderHeight = parseInt($this.css("borderTopWidth"), 10) + parseInt($this.css("borderBottomWidth"), 10);
    //Get padding for element
    tmpPadding = new Array();
    tmpPadding['top'] = $element.css('paddingTop');
    tmpPadding['right'] = $element.css('paddingRight');
    tmpPadding['bottom'] = $element.css('paddingBottom');
    tmpPadding['left'] = $element.css('paddingLeft');
    horizontalWidth = (objectWidth + 2*($.fn.wrShadow.params.shadowWidth)) - 2*($.fn.wrShadow.params.cornerWidth) + borderWidth;
    horizontalWidth += parseInt(tmpPadding['right'], 10) + parseInt(tmpPadding['left'], 10);
    $top = $element.prev().prev().prev();
    $right = $element.next();
    $bottom = $element.next().next().next();
    $left = $element.prev();
      $top.css({
          'width' : horizontalWidth + 'px'
      });
      $right.css({
          'height' : objectHeight + borderHeight + parseInt(tmpPadding['top'], 10) + parseInt(tmpPadding['bottom'], 10) + 'px'
      });
      $bottom.css({
          'width' : horizontalWidth + 'px'
      });
      $left.css({
          'height' : objectHeight + borderHeight + parseInt(tmpPadding['top'], 10) + parseInt(tmpPadding['bottom'], 10) + 'px'
      });
      return true;
  };

  $.fn.wrShadow.defaults = {
    cornerWidth:                11,   //Integer, how wide are the corners?
    shadowWidth:                6,   //Integer, how wide are the shadow-effect
    miniCornerWidth:            3,   //Integer, how wide are the corners for mini-shadow
    miniShadowWidth:            3   //Integer, how wide are the shadow-effect for mini-shadow
  }

  $.fn.wrShadow.params = {
    isMini:                     0,   //Integer/Boolean, is this a mini-shadow (will be set automatically)
    cornerWidth:                0,   //Integer, how wide are the corners?
    shadowWidth:                0   //Integer, how wide are the shadow-effect
  }
})(jQuery);
