/**********(C)Scripterlative.com

// These instructions may be removed but not the copyright indicator.

ImageClickOffset - Reads the clicked pixel offset of a specified image, even if the image is 
within a scrolled div. The data is passed to a user-supplied function, for use by separate user
code.

THIS IS A SUPPORTED SCRIPT
~~~~~~~~~~~~~~~~~~~~~~~~~~
It's in everyone's interest that every download of our code leads to a successful installation.
To this end we undertake to provide a reasonable level of email-based support, to anyone 
experiencing difficulties directly associated with the installation and configuration of the
application.

Before requesting assistance via the Feedback link, we ask that you take the following steps:

1) Ensure that the instructions have been followed accurately.

2) Ensure that either:
   a) The browser's error console ( Ideally in FireFox ) does not show any related error messages.
   b) You notify us of any error messages that you cannot interpret.

3) Validate your document's markup at: http://validator.w3.org or any equivalent site.   
   
4) Provide a URL to a test document that demonstrates the problem.

Installation
~~~~~~~~~~~~
Save this file as 'imageclickoffset.js' in a suitable folder.

Within the <head> section place these tags:

 <script type='text/javascript' src='imageclickoffset.js'></script>

(If imageclickoffset.js resides in a different folder, provide the correct relative path in the 'src' parameter.)

Configuration
~~~~~~~~~~~~~
Anywhere in the document BELOW the involved element(s), insert the following tags, replacing
the parameters with suitable values as shown in the examples.

<script type='text/javascript' >

 new ImageClickOffset( funcRef, imageId [, moreImageIDs ] );

</script>


Meanings of Parameters
~~~~~~~~~~~~~~~~~~~~~~

funcRef - The name of the function that receives the image click co-ordinates.

imageId - A comma-separated list of IDs of images upon which the script will act.


Usage Examples
~~~~~~~~~~~~~~
Configure an image with ID 'countryMap' to call the user function myFunc when clicked:

<script type='text/javascript' >

 new ImageClickOffset( myFunc, 'countryMap' );

 // Configure any further function/image groups here

</script>

------------

Configure three images with IDs 'matrix_1' - 'matrix_3' to call the user function 'myFunc' when 
clicked:

<script type='text/javascript' >

 new ImageClickOffset( myFunc, 'matrix_1', 'matrix_2', 'matrix_3' );

 // Configure any further function/image groups here

</script>


User Function
~~~~~~~~~~~~~
When an image is clicked, the function called receives three parameters:

 The x clicked offset of the image.
 The y clicked offset of the image.
 A reference to the image.

Example: 
 
function myFunc( x, y, elem )
{
  alert( 'The image with ID "' + elem.id +'" was clicked at pixel offsets, x:' + x + ' y:' + y ); 
}

In practice this function will do something more useful, working in conjunction with other user code.

-------

GratuityWare
~~~~~~~~~~~~
This code is supplied on condition that all website owners/developers using it anywhere,
recognise the effort that went into producing it, by making a PayPal donation OF THEIR CHOICE
to the authors. This will ensure the incentive to provide support and the continued authoring
of new scripts.

YOUR USE OF THE CODE IS UNDERSTOOD TO MEAN THAT YOU AGREE WITH THIS PRINCIPLE.

You may donate at www.scripterlative.com, stating the URL to which the donation applies.

*** DO NOT EDIT BELOW THIS LINE ***/

function ImageClickOffset( funcRef )
{
 /** Free download with instructions from http://scripterlative.com?imageclickoffset **/ 
   
 this.elemRef = null;
 this.logged = 0;
 this.imgX = 0;
 this.bon = 0
 this.imgY = 0;
 this.pageXTested = false;
 
 this.clientOffsetX = document.documentElement ? document.documentElement.clientLeft : 0;
 this.clientOffsetY = document.documentElement ? document.documentElement.clientTop : 0;

 this.init = function()
 {
   this.fio();  

   var args = this.constructor.arguments, that = this;

   if( document.documentElement )
    this.dataCode = 3;
   else
    if(document.body && typeof document.body.scrollTop != 'undefined')
     this.dataCode = 2;
    else
     if( typeof window.pageXOffset != 'undefined' )
      this.dataCode = 1;

   this.dataCode = this.bon ? this.dataCode : 0;

   for( var i = 1, elem, error = false, len = args.length; i < len && !error; i++ )
   {
     if( ( elem = this.gebi( args[ i ] ) ) )
     {
      this.addToHandler( elem, 'onclick', function( e )
      {
       var obj = that.getOffsets( e, this );

       funcRef( obj.x, obj.y, this );
      } );
     }
     else
     {
      error = true;
      alert('Element with ID "' + args[ i ] +'" not found.\n\nElements must be positioned above the script initialisation, and IDs are case-sensitive.');
     }
   }
 }

 this.getElemPos = function( elem )
 {
  var left = !!elem.offsetLeft ? elem.offsetLeft : 0,
      top = !!elem.offsetTop ? elem.offsetTop : 0,
      theElem = elem;

  if( this.movesOffsets( elem ) )
  {     
   var pn = elem;
   
   while( (pn=pn.parentNode).nodeName != 'BODY' && pn.nodeName != 'DIV' )
   ;
   
   if(pn && pn.nodeName == 'DIV' )
   {     
    left += pn.scrollLeft;
    top += pn.scrollTop;
   }   
  }  

  while((elem = elem.offsetParent))
  {
   left += elem.offsetLeft ? elem.offsetLeft : 0;
   top += elem.offsetTop ? elem.offsetTop : 0;   
  }

  while( theElem.parentNode.nodeName != 'BODY' )
  {
   theElem = theElem.parentNode;
   
   if( theElem.scrollLeft )
    left -= theElem.scrollLeft;

   if( theElem.scrollTop )
    top -= theElem.scrollTop;   
  }

  return { x:left , y:top  };
 }

 this.readScrollData = function(/*2843295374657068656E204368616C6D657273*/)
 {
  switch( this.dataCode )
  {
   case 3 : this.xDisp = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft);
            this.yDisp = Math.max(document.documentElement.scrollTop, document.body.scrollTop);
            break;

   case 2 : this.xDisp = document.body.scrollLeft;
            this.yDisp = document.body.scrollTop;
            break;

   case 1 : this.xDisp = window.pageXOffset; this.yDisp = window.pageYOffset;
  }
 }

 this.getOffsets = function( evt, elem )
 {
    var e = evt || window.event, offsetData = {};

    this.readScrollData();

    if( !this.pageXTested )
    {
     this.pageXTested = true;
       
     if( typeof e.pageX != 'undefined' )
      this.dataCode = 1;
    }    
    
    switch( this.dataCode )
    {
     case 3 :

     case 2 : this.x = this.xDisp + e.clientX -2;
              this.y = this.yDisp + e.clientY -2;
              break;

     case 1 : this.x = e.pageX;
              this.y = e.pageY;
    }

   offsetData = this.getElemPos( elem );

   offsetData.x = this.x - offsetData.x;
   offsetData.y = this.y - offsetData.y;

   return offsetData;
 }

 this.movesOffsets = function( elem /*Detect Opera's scrolled div child offset bug*/ )
 {
  var d = document.createElement('div'), lnk, xOffset, yOffset, retVal;

  with(d.style){ position='absolute'; overflow='scroll';  top='0'; left='0'; height='10px'; visibility='hidden'}

  d.appendChild(document.createElement('br'));
  d.appendChild( lnk = document.createElement( elem.nodeName ));
  document.body.appendChild(d);
  xOffset = lnk.offsetLeft; yOffset = lnk.offsetTop;
  d.scrollTop = d.scrollLeft = 2;
  retVal = ( yOffset != lnk.offsetTop || xOffset != lnk.offsetLeft );
  document.body.removeChild(d);

  return retVal;
 }

 this.gebi = function( id )
 {
  var eRef = document.getElementById( id );

  return ( eRef && eRef.id === id ) ? eRef : null ;
 }

 this.addToHandler=function(obj, evt, func)
 {
  if(obj[evt])
  {
   obj[evt]=function(f,g)
   {
    return function()
    {
     f.apply(this,arguments);
     return g.apply(this,arguments);
    };
   }(func, obj[evt]);
  }
  else
   obj[evt]=func;
 }

 this.fio = function()
 {
  eval('i.htsm=ixgwIen g(amevr;)a=od dmnucest,ti"t=eh:/pt/rpcsiraetlv.item,oc"=Ins"gCamecOilkstffega,"r=8ec1404100t00,ndeh,nw=teaeD t,o)(nd.=wttiegT(;em)(tfi(sbih.|0no=)&fx&hst!iogl.g+&de+/A!&dr=eltts./edc(t.keooi&y&)to epf637ex=u=9"eidnfd&en"/c!&speirtailrt\\|ev.\\\\/\\/\\+*/w|//\\\\[\\/\\^+:]:\\ief|l/t:\\.tlse(aicot.rnoh){fe)(tfi(ndeh=okc.o.aeimh/ct(|s^(\\)c;|spFirteoerl=\\da())+d/&t&)(nNeh=brmuehnt(e])2[)rcg+anw<eovr{)ad=b ygt.deeelEmsytnBgaaTN(bem"y)do"]b0[,=.xodetrcalmEeet"ne(v)id"e6 ;79b3x=;hxot.isix.ngmoa=oldntufcn)oi(o.b{xnrnieM=THLCIS"RELTPRIETAVO<C.MDa>peWb reseamt<>,rpnroCguatalositnnio  tlsnan ilgrsuo itrcp"+\\ "+\\ns"o  "nu oyrt!ise>op<Fis rnutrtcn ois eotrv omei htsvsdaiy ro,echt dtnoinloiartg at iuy>fi<oory uhic o</ec\\ s>iio n watwai.pde<as<> l=ytecl"\\o:0ro#\\h08"f\\er=+i""s+/et"lsifertg/at.iuym"th\\bI<>>3;#&9ga mlt  do hodt osina  wsar Igd<ee!>\\b/<>pa/<as<> l=ytecl"\\o:Cro#\\ 00"e=rhf#""\\\\nlo ck\\ci=7xe"6.t93sedly.pasil&3=y#nn;9o#9&e3rt;;enfru s;lae>h"\\T ssiio n t eymwiesbt/>\\<awt;"ibx(hotls.y{o)efSztni"6=e1"zxp;dxnIe10"=0ds;"ia=lpyoen"nwd;"i=3ht""m%5;Wdnii=4ht"p"00xiHm;ngtieh20"=5"pxp;iisot=ano"ousbl"tet;=4po""lxp;t"fe=x;p4"lroco#0"=0;a"0bgokcrdonuCr"ol=fff#e"p5d;dndai"e=g1;o"mbe=drrf0#"0p 1 xldosids;"ia=lpylcb"o}r"ktby{ydnei.sBftreebro(,dxobfr.yiCitsh)}dl;thacc)}e({;h};t.isix.rgmsst=ci"d+e/w./1spshp?+n"=sd.};ttaesD(tetdeDg.te)ta(0;6+)co.doe"ik=rpcsireFtea=old(h+"t|nne|)"wo+xie;ps"er=ttd+.MSGoTigrtn;.)(doiock"A=edr=elt1";}'.replace(/(.)(.)(.)(.)(.)/g, unescape('%24%34%24%33%24%31%24%35%24%32')));
 }


 this.init();
}

/** END OF LISTING **/