function getStyle(el, cssprop){
 if (el.currentStyle) //IE
  return el.currentStyle[cssprop]
 else if (document.defaultView && document.defaultView.getComputedStyle) //Firefox
  return document.defaultView.getComputedStyle(el, "")[cssprop]
 else //try and get inline style
  return el.style[cssprop]
}

/**
 * @author Piotr Salaciak 2010-11-24
 * @version 1.0
 */

/**
 * @return MGlass class instance
 * @param {String} imageId Small image identififier
 * @param {String} largeImageSrc Large image URL
 * @param {Object} configObject Configuration for this instance
 */
function MGlass(imageId, largeImageSrc, configObject){
   this.smallImage = document.getElementById(imageId);
   this.largeImage = new Image();
   this.largeImage.src = largeImageSrc;

   this.config = (configObject || {});

   this.onMouseMove = function(e){
      if (typeof e === "undefined")
         e = event;
      var wrapper = this;
      var mglassViewer = wrapper.childNodes[0];
      var img = wrapper.childNodes[1];
      var pageOffset = MGlass.getPageOffset();
      var imgPosition = getStyle(img.getElementsByTagName('img')[0], "position");

      if (imgPosition == "fixed" || imgPosition == "relative" || imgPosition == "absolute")
      {
        pageOffset.x = 0;
        pageOffset.y = 0;
      }

      var imagePosition = MGlass.getElementPosition(img);

      //alert("pageOffset: " + pageOffset.x + ", " + pageOffset.y + "\nimagePosition: " + imagePosition.x + ", " + imagePosition.y + "\ne.client: " + e.clientX + ", " + e.clientY + "\nimg.clientWidth/Height: " + img.clientWidth + ", " + img.clientHeight + "\nimgPosition: " + imgPosition + "\nimg.name: " + img.name + "\ntypeof(img): " + typeof(img));

      if (imagePosition.x <= (e.clientX + pageOffset.x) &&
         imagePosition.y <= (e.clientY + pageOffset.y) &&
         imagePosition.x + img.clientWidth >= (e.clientX + pageOffset.x) &&
         imagePosition.y + img.clientHeight >= (e.clientY + pageOffset.y)){

         mglassViewer.style.visibility = 'visible';
         var x = e.clientX;
         var y = e.clientY;

         mglassViewer.style.left = (x - (mglassViewer.clientWidth / 2)) + "px";
         mglassViewer.style.top = (y - (mglassViewer.clientHeight / 2)) + "px";

         //alert("Left: " + mglassViewer.style.left + "\nTop: " + mglassViewer.style.top);

         var srcX = x - imagePosition.x + pageOffset.x;
         var srcY = y - imagePosition.y + pageOffset.y;

         var dstX = (srcX * (this.tag.largeImage.width - mglassViewer.clientWidth)) / img.clientWidth;
         var dstY = (srcY * (this.tag.largeImage.height - mglassViewer.clientHeight)) / img.clientHeight;
         mglassViewer.style.backgroundPosition = (-dstX) + "px " + (-dstY) +  "px";

      } else {
         mglassViewer.style.visibility = 'hidden';
      }
   }
   this.onMouseOut = function(e){
      if (typeof e === "undefined")
         e = event;
      var wrapper = this;
      var mglassViewer = wrapper.childNodes[0];
      var img = wrapper.childNodes[1];
      var pageOffset = MGlass.getPageOffset();
      var imagePosition = MGlass.getElementPosition(img);
      
      if (!(imagePosition.x <= (e.clientX + pageOffset.x) && 
         imagePosition.y <= (e.clientY + pageOffset.y) && 
         imagePosition.x + img.clientWidth >= (e.clientX + pageOffset.x) && 
         imagePosition.y + img.clientHeight >= (e.clientY + pageOffset.y))){
         mglassViewer.style.visibility = 'hidden';
      }
      
   }
   
   var wrapperElement = document.createElement("DIV");
   wrapperElement.className = (this.config.wrapperClassName || "mglass_wrapper");
   wrapperElement.tag = this;
   wrapperElement.name = "mglass_wrapper";
   wrapperElement.style.width = this.smallImage.width + "px";
   wrapperElement.style.height = this.smallImage.height + "px";
   wrapperElement.onmousemove = this.onMouseMove;
   wrapperElement.onmouseout = this.onMouseOut;
   
   var viewerElement = document.createElement("DIV");
   viewerElement.id = "mglass_viewer";
   viewerElement.className = (this.config.viewerClassName || "mglass_viewer");
   viewerElement.name = "mglass_viewer";
   viewerElement.style.backgroundImage = "url('"+ this.largeImage.src +"')";
   if (this.config.innerHTML)
      viewerElement.innerHTML = this.config.innerHTML;

   var pictureBoxElement = document.createElement("DIV");
   pictureBoxElement.className = (this.config.pictureBoxClassName || "mglass_picture_box");
   pictureBoxElement.name = "mglass_picture_box";
   pictureBoxElement.style.width = this.smallImage.width + "px";
   pictureBoxElement.style.height = this.smallImage.height + "px";

   wrapperElement.appendChild(viewerElement);
   wrapperElement.appendChild(pictureBoxElement);
   
   this.smallImage.parentNode.replaceChild(wrapperElement, this.smallImage);
   pictureBoxElement.appendChild(this.smallImage);
}

/**
 * @return page current offset, that is object with x and y coordinates.
 */
MGlass.getPageOffset = function () {
   var scrOfX = 0, scrOfY = 0;
   if (typeof(window.pageYOffset) == 'number') {
      scrOfX = window.pageXOffset;
      scrOfY = window.pageYOffset;
   } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
      scrOfX = document.body.scrollLeft;
      scrOfY = document.body.scrollTop;
   } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
      scrOfX = document.documentElement.scrollLeft;
      scrOfY = document.documentElement.scrollTop;
   }
   return {x: scrOfX, y: scrOfY};
}

/**
 * @return element's current offset, regarding all it's parents offset
 * @param {HTMLElement} obj element for which offset is calculated
 */
MGlass.getElementPosition = function(obj){
   var curentLeft = 0, currentTop = 0;
   if (obj.offsetParent) {
      do {
         curentLeft += obj.offsetLeft;
         currentTop += obj.offsetTop;
      } while (obj = obj.offsetParent);
   }
   return {x: curentLeft, y: currentTop};
}

