      /* init popup div and preloader */

      function zPdebug (s) {
        return true;
        window.status = s;
        if (document.getElementById ('debug')) {
          document.getElementById ('debug').innerHTML = document.getElementById ('debug').innerHTML + s + '<br>\n';
        }
        return true;
      }

      function PreloadedImage (src, loadHandler, boundTo) {
        zPdebug ('new preloaded image ' + src);
        var img = new Image ();
        img.PISrc      = src;
        img.PILoaded   = false;
        img.PIOnload   = loadHandler;
        img.onload = function () {
          this.PIWidth  = this.width;
          this.PIHeight = this.height;
          this.PILoaded = true;
          zPdebug ('image preloaded ' + src + ' ' + this.width + ' ' + this.height);
          if (!this.PIOnload)
            return true;
          if (!boundTo)
            boundTo = this;
          this.PIOnload.call (boundTo, this);
          this.PIOnload = '';
          return true;
        }
        img.onerror = function () {
          alert (this.newsrc + ' not loaded');
        }
        img.src = src;
        return img;
      }

      function zPPreloaderInit (o, bigsrc, title, text) {
      
        if (!window.zoomPopup) {

          zPdebug ('zoomPopup init ' + bigsrc);

          window.zoomPopup = {
            'zoom'      : document.getElementById ('zoom')        || alert ('picture zoom div not found'),
            'image'     : document.getElementById ('zoomImg')     || alert ('picture zoom img not found'),
            'loadImg'   : document.getElementById ('zoomLoadImg') || alert ('picture zoom loader not found'),
            'titleDiv'  : document.getElementById ('zoomTitle'),
            'textDiv'   : document.getElementById ('zoomText'),
            'nowShowing': false,
            'nowLoading': false,
            'delaying'  : 100,
            'show'      : function (src, title, text, loading) {

  //            this.close ();
              this.clearDelayed ();

              /* show image alt */
              this.src                      = src;
              this.image.alt                = title;

              /* show title */
              if (this.titleDiv) {
                this.titleDiv.style.display = title ? 'block' : 'none';
                this.titleDiv.innerHTML     = title;
              }
              /* show text */
              if (this.textDiv) {
                this.textDiv.style.display  = text ? 'block' : 'none';
                this.textDiv.innerHTML      = text;
              }

              this.loading                  = loading;
              this.nowShowing               = src && !loading ? src : false;
              this.nowLoading               = src &&  loading ? src : false;

              /* load image to get dimensions and center after loading */
              this.plImg =
                new PreloadedImage (
                  src,
                  function () {
                    return window.zoomPopup.center (this.PIWidth, this.PIHeight);
                  }
                );

              return true;
            },
            'center'   : function (width, height) {

/*
              this.titleDiv.style.width   = this.image.width + 'px';
              this.textDiv.style.width    = this.image.width + 'px';
              this.titleDiv.style.width   = this.width + 'px';
              this.textDiv.style.width    = this.width + 'px';
*/

              /* get window dims */
              var top           = !window.pageYOffset ? document.documentElement.scrollTop  : window.pageYOffset;
              var left          = !window.pageXOffset ? document.documentElement.scrollLeft : window.pageXOffset;
              var winWidth      = window.innerWidth  ? window.innerWidth  : document.documentElement.clientWidth;
              var winHeight     = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight;

              /* display offscreen to measure */
              this.zoom.style.left     = (-width  - 2000) + 'px';
              this.zoom.style.top      = (-height - 2000) + 'px';
              this.zoom.style.display  = 'block';

              /* set text divs width - IE gives the dimensions of prev image loaded */
              this.titleDiv.style.width   = width + 'px';
              this.textDiv.style.width    = width + 'px';

              /* load image */
              this.image.src = this.src;

              /* IE display none bug */
              this.loadImg.style.display    = this.loading ? 'block' : 'none';
              this.loadImg.style.visibility = this.loading ? 'visible' : 'hidden';



              /* measure extends */
              var width         = this.zoom.scrollWidth;
              var height        = this.zoom.scrollHeight;
//              alert ('center: width ' + width + ' height ' + height);


              /* hide */
//              alert ('stop: measured width ' + width + ' measured height ' + height);
              this.zoom.style.display     = 'none';

              /* set position and dimensions */
              this.zoom.style.top   = Math.max (0, Math.round ((winHeight - height) / 2 + top)) + 'px';
              this.zoom.style.left  = Math.max (0, Math.round ((winWidth  - width)  / 2 + left)) + 'px';
//              alert (winWidth + ' ' + winHeight + ' ' + left + ' ' + top + ' ' + z.width + ' ' + z.height);

              /* show */
              this.zoom.style.display     = 'block';
              return true;
            },
            'isShowing': function (src) {
              return src == this.nowShowing;
            },
            'isLoading': function (src) {
              return src == this.nowLoading;
            },
            'timeout'     : false,
            'showDelayed' : function (src, title, text) {
              this.clearDelayed ();
              this.timeout = window.setTimeout (
                function () {
                  zoomPopup.show (src, title, text, false);
                },
                this.delaying
              );
              return true;
            },
            'clearDelayed': function () {
              if (this.timeout) {
                window.clearTimeout (this.timeout);
              }
              this.timeout = false;
              return true;
            },
            'close': function () {
              zPdebug ('close');
              if (this.timeout) {
                window.clearTimeout (this.timeout);
              }
              this.loadImg.style.display  = 'none';
              if (this.titleDiv) {
                this.titleDiv.display     = 'none';
              }
              if (this.textDiv) {
                this.textDiv.display      = 'none';
              }
              this.zoom.style.display     = 'none';
              this.timeout       = false;
              this.nowShowing    = false;
              this.nowLoading    = false;
              this.image.onload = function () {
                zPdebug ('load fil ' + this.width + ' ' + this.height);
                this.onload = '';
                return true;
              }
              this.image.src = '' /* fil.gif */;
              return true;
            }
          }
          zoomPopup.image.onclick = function () {
            zoomPopup.close ();
            return false;
          }
        }

        /* find source image */
        var img = o;
        if (o.tagName != 'IMG') {
          var imgs = img.getElementsByTagName ('IMG');
          if (!imgs.length) {
            alert ('source img not found');
            return false;
          }
          img = imgs [0];
        }

        if (!img.zPPreloader) {

          zPdebug ('zPPreloader init ' + bigsrc);

          img.zPPreloader = {
            'img'         : img,
            'src'         : img.src,
            'bigsrc'      : bigsrc,
            'title'       : title,
            'text'        : text,
            'onclick'     : function () {
            
              zPdebug ('zPPreloader onclick ' + bigsrc);
              
              /* this img is already popped - close it */
              if (zoomPopup.isShowing (this.bigsrc)) {
                zoomPopup.close ();
              }
              /* show small img and "loading .." */
              zoomPopup.show        (this.src,    this.title, this.text, true);
//              alert ('wait');

              /* show big img after loading */
              /* load image to get dimensions and center after loading */
              this.plImg =
                new PreloadedImage (
                  bigsrc,
                  function () {
                    return zoomPopup.showDelayed (this.bigsrc, this.title, this.text, false);
                  },
                  this
                );
              this.plImg.pl = this;
              return false;
            }
          }

          /* set new image or object click handler */
          o.img = img;
          o.onclick = function () {
            this.img.zPPreloader.onclick ();
            return false;
          }
        }
        return true;
      }
      
      /* called with onclick="return ZPClick" */
      function zPClick (o, bigsrc, title, text) {
        zPdebug ('zPClick ' + bigsrc);

        /* init */
        if (!zPPreloaderInit (o, bigsrc, title, text)) {
          return true;
        };

        /* do the click */
        return o.onclick ();
      }

