/*
ҪΪElementṩȡߴصļݷ
*/
(function(){

Element.implement({

 //ʹӷΧָ
 scrollTo: function(x, y){
  //ǰbodyҳĹ
  if (isBody(this)){
   this.getWindow().scrollTo(x, y);
  } else {
   this.scrollLeft = x;
   this.scrollTop = y;
  }
  return this;
 },

 //ȡĲֳߴ
 getSize: function(){
  if (isBody(this)) return this.getWindow().getSize();
  return {x: this.offsetWidth, y: this.offsetHeight};
 },

 //ȡĹߴ
 getScrollSize: function(){
  if (isBody(this)) return this.getWindow().getScrollSize();
  return {x: this.scrollWidth, y: this.scrollHeight};
 },

 //ȡλ
 getScroll: function(){
  if (isBody(this)) return this.getWindow().getScroll();
  return {x: this.scrollLeft, y: this.scrollTop};
 },

 //ȡĵĹλ
 getScrolls: function(){
  var element = this, position = {x: 0, y: 0};
  while (element && !isBody(element)){
   position.x += element.scrollLeft;
   position.y += element.scrollTop;
   element = element.parentNode;
  }
  return position;
 },

 //ȡܵƫ
 getOffsets: function(){
  var element = this, position = {x: 0, y: 0};
  //Ǹڵ,Ϊԭ
  if (isBody(this)) return position;

  while (element && !isBody(element)){
   position.x += element.offsetLeft;
   position.y += element.offsetTop;

   if (Browser.Engine.gecko){
    //firefoxĴ,ʹúģ,Ҫϱ߿Ŀ
    if (!borderBox(element)){
     position.x += leftBorder(element);
     position.y += topBorder(element);
    }
    var parent = element.parentNode;
    if (parent && styleString(parent, 'overflow') != 'visible'){
     position.x += leftBorder(parent);
     position.y += topBorder(parent);
    }
   } else if (element != this && (Browser.Engine.trident || Browser.Engine.webkit)){
    //IESafariҲҪϱ߿,ֻOperaȽϷϱ׼,Safari֮
    position.x += leftBorder(element);
    position.y += topBorder(element);
   }

   element = element.offsetParent;
   if (Browser.Engine.trident){
    //IEûhasLayoutelement
    while (element && !element.currentStyle.hasLayout) element = element.offsetParent;
   }
  }
  //firefox²ʹúģͽʱҪټȥǰ߿
  if (Browser.Engine.gecko && !borderBox(this)){
   position.x -= leftBorder(this);
   position.y -= topBorder(this);
  }
  return position;
 },

 //ȡֵ,ṩrelative,򷵻ralativeֵ
 getPosition: function(relative){
  //ڵΪԭ
  if (isBody(this)) return {x: 0, y: 0};
  //ȡƫֵ͹λ
  var ffset = this.getOffsets(), scroll = this.getScrolls();
  //õֵ
  var position = {x: offset.x - scroll.x, y: offset.y - scroll.y};
  //ֵ
  var relativePosition = (relative && (relative = $(relative))) ? relative.getPosition() : {x: 0, y: 0};
  return {x: position.x - relativePosition.x, y: position.y - relativePosition.y};
 },

 //ȡͳߴ
 getCoordinates: function(element){
  //ڵ㴦
  if (isBody(this)) return this.getWindow().getCoordinates();
  //ֱȡߴ
  var position = this.getPosition(element), size = this.getSize();
  //µıʾʽ
  var bj = {left: position.x, top: position.y, width: size.x, height: size.y};
  //ļ
  obj.right = obj.left + obj.width;
  obj.bottom = obj.top + obj.height;
  return obj;
 },

 //ʱ,margin-leftmargin-topӰ
 computePosition: function(obj){
  return {left: obj.x - styleNumber(this, 'margin-left'), top: obj.y - styleNumber(this, 'margin-top')};
 },

 //λ
 position: function(obj){
  return this.setStyles(this.computePosition(obj));
 }

});

//DocumentWindowʵElementͬ,ΪʵбһElement
Native.implement([Document, Window], {

 //ȡߴ
 getSize: function(){
  var win = this.getWindow();
  //OperaSafariĴ
  if (Browser.Engine.presto || Browser.Engine.webkit) return {x: win.innerWidth, y: win.innerHeight};
  var doc = getCompatElement(this);
  return {x: doc.clientWidth, y: doc.clientHeight};
 },

 //ȡ
 getScroll: function(){
  var win = this.getWindow();
  var doc = getCompatElement(this);
  return {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop};
 },

 //ȡߴ
 getScrollSize: function(){
  var doc = getCompatElement(this);
  var min = this.getSize();
  return {x: Math.max(doc.scrollWidth, min.x), y: Math.max(doc.scrollHeight, min.y)};
 },

 //λ
 getPosition: function(){
  return {x: 0, y: 0};
 },

 //ȡߴ
 getCoordinates: function(){
  var size = this.getSize();
  return {top: 0, left: 0, bottom: size.y, right: size.x, height: size.y, width: size.x};
 }

});

// ˽з

//ȡʱʽ
var styleString = Element.getComputedStyle;

//ȡʱʽԵֵ
function styleNumber(element, style){
 return styleString(element, style).toInt() || 0;
};

//ȡгߴmozillaͥ˽
function borderBox(element){
 return styleString(element, '-moz-box-sizing') == 'border-box';
};

//ȡϱ߿Ŀ
function topBorder(element){
 return styleNumber(element, 'border-top-width');
};

//ȡ߿
function leftBorder(element){
 return styleNumber(element, 'border-left-width');
};

//elementǷbodyhtmlڵ
function isBody(element){
 return (/^(?:body|html)$/i).test(element.tagName);
};

//ݵǰĵǷʹñ׼ģʽҳڵ,htmlbody
function getCompatElement(element){
 var doc = element.getDocument();
 return (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
};

})();

//

Native.implement([Window, Document, Element], {

 //ȡ߶,getSize
 getHeight: function(){
  return this.getSize().y;
 },

 //ȡ,getSize
 getWidth: function(){
  return this.getSize().x;
 },

 //ȡy,getScroll
 getScrollTop: function(){
  return this.getScroll().y;
 },

 //ȡx,getScroll
 getScrollLeft: function(){
  return this.getScroll().x;
 },

 //ȡ߶,getScrollSize
 getScrollHeight: function(){
  return this.getScrollSize().y;
 },

 //ȡ,getScrollSize
 getScrollWidth: function(){
  return this.getScrollSize().x;
 },

 //ȡy,getPosition
 getTop: function(){
  return this.getPosition().y;
 },

 //ȡx,getPosition
 getLeft: function(){
  return this.getPosition().x;
 }

});

