//MooTools More, <http://mootools.net/more>. Copyright (c) 2006-2009 Aaron Newton <http://clientcide.com/>, Valerio Proietti <http://mad4milk.net> & the MooTools team <http://mootools.net/developers>, MIT Style License.

MooTools.More={version:"1.2.2.2"};var Asset={javascript:function(f,d){d=$extend({onload:$empty,document:document,check:$lambda(true)},d);var b=new Element("script",{src:f,type:"text/javascript"});
var e=d.onload.bind(b),a=d.check,g=d.document;delete d.onload;delete d.check;delete d.document;b.addEvents({load:e,readystatechange:function(){if(["loaded","complete"].contains(this.readyState)){e();
}}}).set(d);if(Browser.Engine.webkit419){var c=(function(){if(!$try(a)){return;}$clear(c);e();}).periodical(50);}return b.inject(g.head);},css:function(b,a){return new Element("link",$merge({rel:"stylesheet",media:"screen",type:"text/css",href:b},a)).inject(document.head);
},image:function(c,b){b=$merge({onload:$empty,onabort:$empty,onerror:$empty},b);var d=new Image();var a=$(d)||new Element("img");["load","abort","error"].each(function(e){var f="on"+e;
var g=b[f];delete b[f];d[f]=function(){if(!d){return;}if(!a.parentNode){a.width=d.width;a.height=d.height;}d=d.onload=d.onabort=d.onerror=null;g.delay(1,a,a);
a.fireEvent(e,a,1);};});d.src=a.src=c;if(d&&d.complete){d.onload.delay(1);}return a.set(b);},images:function(d,c){c=$merge({onComplete:$empty,onProgress:$empty,onError:$empty},c);
d=$splat(d);var a=[];var b=0;return new Elements(d.map(function(e){return Asset.image(e,{onload:function(){c.onProgress.call(this,b,d.indexOf(e));b++;if(b==d.length){c.onComplete();
  } 
}, onerror: function () { c.onError.call(this, b, d.indexOf(e)); b++; if (b == d.length) { c.onComplete(); } } 
});
}));
} 
};

Element.implement({

  measure: function (fn) {
    var vis = function (el) {
      return !!(!el || el.offsetHeight || el.offsetWidth);
    };
    if (vis(this)) return fn.apply(this);
    var parent = this.getParent(),
			restorers = [],
			toMeasure = [];
    while (!vis(parent) && parent != document.body) {
      toMeasure.push(parent.expose());
      parent = parent.getParent();
    }
    var restore = this.expose();
    var result = fn.apply(this);
    restore();
    toMeasure.each(function (restore) {
      restore();
    });
    return result;
  },

  expose: function () {
    if (this.getStyle('display') != 'none') return $empty;
    var before = this.style.cssText;
    this.setStyles({
      display: 'block',
      position: 'absolute',
      visibility: 'hidden'
    });
    return function () {
      this.style.cssText = before;
    } .bind(this);
  },

  getDimensions: function (options) {
    options = $merge({ computeSize: false }, options);
    var dim = {};
    var getSize = function (el, options) {
      return (options.computeSize) ? el.getComputedSize(options) : el.getSize();
    };
    var parent = this.getParent('body');
    if (parent && this.getStyle('display') == 'none') {
      dim = this.measure(function () {
        return getSize(this, options);
      });
    } else if (parent) {
      try { //safari sometimes crashes here, so catch it
        dim = getSize(this, options);
      } catch (e) { }
    } else {
      dim = { x: 0, y: 0 };
    }
    return $chk(dim.x) ? $extend(dim, { width: dim.x, height: dim.y }) : $extend(dim, { x: dim.width, y: dim.height });
  },

  getComputedSize: function (options) {
    options = $merge({
      styles: ['padding', 'border'],
      plains: {
        height: ['top', 'bottom'],
        width: ['left', 'right']
      },
      mode: 'both'
    }, options);
    var size = { width: 0, height: 0 };
    switch (options.mode) {
      case 'vertical':
        delete size.width;
        delete options.plains.width;
        break;
      case 'horizontal':
        delete size.height;
        delete options.plains.height;
        break;
    }
    var getStyles = [];
    //this function might be useful in other places; perhaps it should be outside this function?
    $each(options.plains, function (plain, key) {
      plain.each(function (edge) {
        options.styles.each(function (style) {
          getStyles.push((style == 'border') ? style + '-' + edge + '-' + 'width' : style + '-' + edge);
        });
      });
    });
    var styles = {};
    getStyles.each(function (style) { styles[style] = this.getComputedStyle(style); }, this);
    var subtracted = [];
    $each(options.plains, function (plain, key) { //keys: width, height, plains: ['left', 'right'], ['top','bottom']
      var capitalized = key.capitalize();
      size['total' + capitalized] = size['computed' + capitalized] = 0;
      plain.each(function (edge) { //top, left, right, bottom
        size['computed' + edge.capitalize()] = 0;
        getStyles.each(function (style, i) { //padding, border, etc.
          //'padding-left'.test('left') size['totalWidth'] = size['width'] + [padding-left]
          if (style.test(edge)) {
            styles[style] = styles[style].toInt() || 0; //styles['padding-left'] = 5;
            size['total' + capitalized] = size['total' + capitalized] + styles[style];
            size['computed' + edge.capitalize()] = size['computed' + edge.capitalize()] + styles[style];
          }
          //if width != width (so, padding-left, for instance), then subtract that from the total
          if (style.test(edge) && key != style &&
						(style.test('border') || style.test('padding')) && !subtracted.contains(style)) {
            subtracted.push(style);
            size['computed' + capitalized] = size['computed' + capitalized] - styles[style];
          }
        });
      });
    });

    ['Width', 'Height'].each(function (value) {
      var lower = value.toLowerCase();
      if (!$chk(size[lower])) return;

      size[lower] = size[lower] + this['offset' + value] + size['computed' + value];
      size['total' + value] = size[lower] + size['total' + value];
      delete size['computed' + value];
    }, this);

    return $extend(styles, size);
  }

});
