/****************************************************************************
 * Copyright (c) 1998-2008 Luna Imaging, Inc.  All Rights Reserved.
 *
 * This software is confidential and proprietary information of
 * Luna Imaging, Inc.  ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Luna Imaging, Inc.
 *
 * The software may not be copied, reproduced, translated or reduced to
 * any electronic medium or machine-readable form without
 * the prior written consent of Luna Imaging.
 *
 * You are not allowed to distribute the binary and source code
 * (if released) to third parties, without the prior written consent from
 * Luna Imaging.
 *
 * You are not allowed to reverse engineer, disassemble or decompile
 * code, or make any modifications of the binary or source code, remove
 * or alter any trademark, logo, copyright or other proprietary notices,
 * legends, symbols, or labels in the Software.
 *
 * You are not allowed to sub-license the Software or any derivative
 * work based on or derived from the Software.
 *
 * LUNA IMAGING MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
 * SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
 * NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
 * A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, LUNA IMAGING SHALL NOT BE
 * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING,
 * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 *
 *  cruiz10020@yahoo.com
 *
 *  QuickView.js
 *
 *  Structure:
 *
 *
 *  Requires:
 *    prototype.js - http://www.prototypejs.org/
 *
 *  Development History:
 *    8-26-2008       - created
 *
 *******************************************************************************/

function QuickView()
{
  // html elements
  this.mContainer;
  this.mPanel;
  this.mImageContainer;
  this.mScrollingContainer;
  this.mNextButton;
  this.mPrevButton;
  this.mCenterOnCurrentButtonLeft;
  this.mCenterOnCurrentButtonRight;
  this.mBrowseAllLink;
  this.mPreviewContainer;
  this.mPreviewImage;

  // js objects

  // attributes
  this.mImageInfos = $([]);
  this.mImages = $([]);
  this.mRequestedImages = $([]);
  this.mAlreadyRequestedImages = $([]);
  this.mPlacholderImageUrl;
  this.mErrorImageUrl;
  this.mFunctionFetchImages;
  this.mFunctionCreateImageLinkUrl;
  this.mCurrentImageOffset = 0;
  this.mOriginalImageOffset = 0;
  this.mImageRange = $([]);
  this.mTotalNumberOfImages = 0;
  this.mAdvanceTimeout = null;

  // flags
  this.mAnimate = true;
  this.mHideBrowseAllLink = true;
  this.mShowMagnification = true;

  this.ADVANCE_IMAGE_DELAY = 175;

  this.MAX_IMAGE_SIZE = 96;
  this.GAP_SIZE = 5;

  this.CLASSNAME = 'quickView';
  this.NEXT_BUTTON_CLASSNAME = 'nextButton';
  this.PREV_BUTTON_CLASSNAME = 'prevButton';
  this.CENTER_LEFT_BUTTON_CLASSNAME = 'centerLeftButton';
  this.CENTER_RIGHT_BUTTON_CLASSNAME = 'centerRightButton';
  this.BROWSE_ALL_LINK_CLASSNAME = 'browseAllLink';
  this.IMAGE_CONTAINER_CLASSNAME = 'imageContainer';

  this.BROWSE_ALL_LINK_TEXT = 'Thumbnails';
  this.NEXT_BUTTON_TEXT = 'Click to view the next image or hold to scroll quickly.';
  this.PREV_BUTTON_TEXT = 'Click to view the previous image or hold to scroll quickly.';
  this.CENTER_BUTTON_TEXT = 'Click to center on this page\'s image.'

  this.init = function()
  {
    this.mPanel = $( document.createElement( 'div' ) );
    this.mImageContainer = $( document.createElement( 'div' ) );
    this.mScrollingContainer = $( document.createElement( 'div' ) );
    this.mNextButton = $( document.createElement( 'a' ) );
    this.mPrevButton = $( document.createElement( 'a' ) );
    this.mCenterOnCurrentButtonLeft = $( document.createElement( 'a' ) );
    this.mCenterOnCurrentButtonRight = $( document.createElement( 'a' ) );
    this.mBrowseAllLink = $( document.createElement( 'a' ) );
    this.mPreviewContainer = $( document.createElement( 'div' ) );
    this.mPreviewImage = $( document.createElement( 'img' ) );

    this.mPreviewContainer.appendChild( this.mPreviewImage );

    this.mImageContainer.appendChild( this.mScrollingContainer );

    this.mPanel.appendChild( this.mBrowseAllLink );
    this.mPanel.appendChild( this.mCenterOnCurrentButtonLeft );
    this.mPanel.appendChild( this.mCenterOnCurrentButtonRight );
    this.mPanel.appendChild( this.mNextButton );
    this.mPanel.appendChild( this.mImageContainer );
    this.mPanel.appendChild( this.mPrevButton );
    this.mPanel.appendChild( this.mPreviewContainer );
    this.mContainer.appendChild( this.mPanel );

    this.mNextButton.href = 'javascript: var button';
    this.mNextButton.title = this.NEXT_BUTTON_TEXT;
    this.mPrevButton.href = 'javascript: var button';
    this.mPrevButton.title = this.PREV_BUTTON_TEXT;
    this.mCenterOnCurrentButtonLeft.href = 'javascript: var button';
    this.mCenterOnCurrentButtonLeft.title = this.CENTER_BUTTON_TEXT;
    this.mCenterOnCurrentButtonRight.href = 'javascript: var button';
    this.mCenterOnCurrentButtonRight.title = this.CENTER_BUTTON_TEXT;


    this.mPanel.addClassName( this.CLASSNAME );
    this.mNextButton.addClassName( this.NEXT_BUTTON_CLASSNAME );
    this.mPrevButton.addClassName( this.PREV_BUTTON_CLASSNAME );
    this.mBrowseAllLink.addClassName( this.BROWSE_ALL_LINK_CLASSNAME );
    this.mImageContainer.addClassName( this.IMAGE_CONTAINER_CLASSNAME );
    this.mCenterOnCurrentButtonLeft.addClassName(this.CENTER_LEFT_BUTTON_CLASSNAME );
    this.mCenterOnCurrentButtonRight.addClassName(this.CENTER_RIGHT_BUTTON_CLASSNAME );

    this.mBrowseAllLink.update( this.BROWSE_ALL_LINK_TEXT );
    if( this.mHideBrowseAllLink == true )
    {
      this.mBrowseAllLink.hide();
    }

    // register events
    var qv = this;
    /*
    this.mNextButton.ondblclick = function(e)
    {
      qv.mNextButton.blur();

      // advance by one
      qv.advance( 1 );
    };
    */

    this.mNextButton.onmousedown = function(e)
    {
      qv.mNextButton.blur();

      // advance by one
      qv.advance( 1 );

      // call our selves in a bit
      qv.mAdvanceTimeout = setTimeout( qv.mNextButton.onmousedown, qv.ADVANCE_IMAGE_DELAY );
    };

    this.mNextButton.onmouseup = function(e)
    {
      qv.mNextButton.blur();

      // top the next call to advance, breaking the cycle
      if( qv.mAdvanceTimeout )
      {
        clearTimeout( qv.mAdvanceTimeout );
      }
    };

    this.mNextButton.onmouseout = function(e)
    {
      qv.mNextButton.blur();

      // top the next call to advance, breaking the cycle
      if( qv.mAdvanceTimeout )
      {
        clearTimeout( qv.mAdvanceTimeout );
      }
    };

    /*
    this.mPrevButton.ondblclick = function(e)
    {
      qv.mPrevButton.blur();

      // advance by one
      qv.advance( -1 );
    };
    */

    this.mPrevButton.onmousedown = function(e)
    {
      qv.mPrevButton.blur();

      // advance by one
      qv.advance( -1 );

      // call our selves in a bit
      qv.mAdvanceTimeout = setTimeout( qv.mPrevButton.onmousedown, qv.ADVANCE_IMAGE_DELAY );
    };

    this.mPrevButton.onmouseup = function(e)
    {
      qv.mPrevButton.blur();

      // top the next call to advance, breaking the cycle
      if( qv.mAdvanceTimeout )
      {
        clearTimeout( qv.mAdvanceTimeout );
      }
    };

    this.mPrevButton.onmouseout = function(e)
    {
      qv.mPrevButton.blur();

      // top the next call to advance, breaking the cycle
      if( qv.mAdvanceTimeout )
      {
        clearTimeout( qv.mAdvanceTimeout );
      }
    };

    this.mCenterOnCurrentButtonLeft.onclick = function(e)
    {
      this.blur();
      qv.advanceToImage( qv.mOriginalImageOffset );
    };

    this.mCenterOnCurrentButtonRight.onclick = function(e)
    {
      this.blur();
      qv.advanceToImage( qv.mOriginalImageOffset );
    };

    this.mPreviewContainer.onmouseout = function()
    {
      qv.mPreviewContainer.hide();
    };

    this.mPanel.style.position = 'absolute';

    this.mScrollingContainer.style.overflow = 'hidden';

    this.mImageContainer.style.position = 'absolute';
    this.mImageContainer.style.overflow = 'hidden';

    this.mNextButton.style.position = 'absolute';
    this.mPrevButton.style.position = 'absolute';
    this.mCenterOnCurrentButtonLeft.style.position = 'absolute';
    this.mCenterOnCurrentButtonRight.style.position = 'absolute';
    this.mBrowseAllLink.style.position = 'absolute';

    this.mPreviewContainer.hide();
    this.mPreviewContainer.style.position = 'absolute';
    this.mPreviewContainer.style.overflow = 'hidden';
    this.mPreviewContainer.style.backgroundColor = 'black';
    this.mPreviewContainer.style.border = '1px solid #555250';
    this.mPreviewContainer.style.left = 0 + 'px';
    this.mPreviewContainer.style.top = 0 + 'px';


    this.resize();
    this.updatePosition();
  };

  this.render = function( element )
  {
    this.mContainer = element;
    this.init();
  };

  this.advance = function( byHowMany )
  {
    if( ( ( this.mImageRange[1] + byHowMany ) <= ( this.mTotalNumberOfImages - 1 ) ) &&
        ( ( this.mImageRange[0] + byHowMany ) >= 0 ) )
    {
      this.mCurrentImageOffset += byHowMany;
      this.mImageRange[0] += byHowMany;
      this.mImageRange[1] += byHowMany;

      this.updateImages();
    }
  };

  this.advanceToImage = function( offset )
  {
    var byHowMany = ( offset - this.mCurrentImageOffset );
    this.advance( byHowMany );
  };

  this.resize = function()
  {
    this.mPanel.style.width = ( 187 ) + 'px';
    this.mPanel.style.height = ( 58 ) + 'px';

    // everything based on the panel dimensions
    var broseAllLinkDimensions = [0,0];
    var borderOffset = jshBorderOffsets( [this.mPrevButton, this.mCenterOnCurrentButtonLeft], [0,0] );
    if( this.mHideBrowseAllLink != true )
    {
      borderOffset = jshBorderOffsets( [this.mPrevButton, this.mCenterOnCurrentButtonLeft, this.mBrowseAllLink], [0,0] );
      broseAllLinkDimensions = [ this.mBrowseAllLink.getWidth(), this.mBrowseAllLink.getHeight() ];
    }

    var height = ( this.mPanel.getHeight() - ( borderOffset[1] + broseAllLinkDimensions[1] ) );

    this.mPrevButton.style.height = Math.round( 2 * height / 3 ) + 'px';
    this.mNextButton.style.height = this.mPrevButton.style.height;
    this.mCenterOnCurrentButtonLeft.style.height = Math.round( height / 3 ) + 'px';;
    this.mCenterOnCurrentButtonRight.style.height = this.mCenterOnCurrentButtonLeft.style.height;

    this.mImageContainer.style.width = ( this.mPanel.getWidth() -  ( this.mPrevButton.getWidth() + this.mNextButton.getWidth() ) ) + 'px';
    this.mImageContainer.style.height = ( height + borderOffset[1] - jshBorderOffset( this.mImageContainer, [0,0] )[1] ) + 'px';

    this.mScrollingContainer.style.width = ( this.mImageContainer.getHeight() * this.mTotalNumberOfImages ) + 'px';

    // now that we are sized correctly, lets figure out the image range to display
    this.mImageRange = this.calculateOffset();
  };

  this.updatePosition = function()
  {
    var borderOffset = [0,0];
    var broseAllLinkDimensions = [0,0];
    if( this.mHideBrowseAllLink != true )
    {
      borderOffset = jshBorderOffset( this.mBrowseAllLink, [0,0] );
      broseAllLinkDimensions = [ this.mBrowseAllLink.getWidth(), this.mBrowseAllLink.getHeight() ];
    }

    this.mCenterOnCurrentButtonLeft.style.left = ( 0 ) + 'px';
    this.mCenterOnCurrentButtonLeft.style.top = ( broseAllLinkDimensions[1] + borderOffset[1] ) + 'px';

    this.mPrevButton.style.left = ( 0 ) + 'px';
    this.mPrevButton.style.bottom = ( 0 ) + 'px';

    this.mImageContainer.style.backgroundColor = 'black';
    this.mImageContainer.style.left = ( this.mPrevButton.getWidth() ) + 'px';
    this.mImageContainer.style.top = ( broseAllLinkDimensions[1] + borderOffset[1] ) + 'px';

    this.mNextButton.style.right = ( 0 ) + 'px';
    this.mNextButton.style.bottom = ( 0 ) + 'px';

    this.mCenterOnCurrentButtonRight.style.right = ( 0 ) + 'px';
    this.mCenterOnCurrentButtonRight.style.top = ( broseAllLinkDimensions[1] + borderOffset[1] ) + 'px';

    this.mBrowseAllLink.style.right = ( 0 ) + 'px';
    this.mBrowseAllLink.style.top = ( -2 ) + 'px';
  };

  this.updateImages = function()
  {
    // figure out which images to show based on current index
    var start = this.mImageRange[0];
    var end = this.mImageRange[1];
    var borderOffset = jshBorderOffset( this.mImageContainer );
    for( var i = start; i <= end; i++ )
    {
      // do we have this one already created / loaded?
      if( ! this.mImages[i] )
      {
        // create and insert
        this.mImages[i] = $( document.createElement( 'div' ) );

        this.mImages[i].style.backgroundImage = 'url(' + this.mPlacholderImageUrl + ')';
        this.mImages[i].style.backgroundPosition = 'center center';
        this.mImages[i].style.backgroundRepeat = 'no-repeat';
        jshSetFloat( this.mImages[i], 'left' );
        this.mImages[i].style.overflow = 'hidden';
        this.mImages[i].style.textAlign = 'left';
        this.mImages[i].style.width = ( this.mImageContainer.getHeight() - borderOffset[1] ) + 'px';
        this.mImages[i].style.height = ( this.mImageContainer.getHeight() - borderOffset[1] ) + 'px';
        this.insertImage( this.mImages[i], i );

        // dont have that lets request it
        if( ! this.mImageInfos[i] )
        {
          this.requestImages( i );
        }
      }

      // fetch image
      if( this.mImageInfos[i] )
      {
       this.preloadImage( this.mImageInfos[i].urlSize0, i );

       if( this.mImageInfos[i].displayName )
       {
         this.mImages[i].title = this.mImageInfos[i].displayName;
       }
      }
    }

    //$('q').value += 's: ' + start + ', ' + end;
    this.focusOnImage( this.mImages[start] );
  };

  this.insertImage = function( image, offset )
  {
    if( image )
    {
      image.offsetIndex = offset;

      var referenceImage = this.findRefernceImage( offset );
      if( referenceImage != null )
      {
        this.mScrollingContainer.insertBefore( image, referenceImage );

        // need to compensate the scroll since the insertion
        // causes the scroll value to change.
        this.mImageContainer.scrollLeft += image.getWidth();
      }
      else
      {
        // tack it on at the end
        this.mScrollingContainer.appendChild( image );
      }
    }
  };

  this.focusOnImage = function( currentImage )
  {
    var scrollLeft = currentImage.getWidth() * jshIndexOfNode( currentImage );
    if( this.mAnimate == true )
    {
      // animate the scrolling
      ElementEffects.animateScroll( this.mImageContainer, [scrollLeft, 0], 50, .50, null );
    }
    else
    {
      // no animation, just jump straight to it.
      this.mImageContainer.scrollLeft = scrollLeft;
    }
  };

  this.calculateOffset = function()
  {
    var size = this.mImageContainer.getWidth();
    var maxVisibleImages = Math.ceil( size / this.mImageContainer.getHeight() );
    var toReturn = $([0,0]);

    if( this.mTotalNumberOfImages < maxVisibleImages )
    {
      maxVisibleImages = this.mTotalNumberOfImages;
    }
	
    // left most offset from current image index
    toReturn[0] = ( this.mCurrentImageOffset - Math.floor( ( maxVisibleImages - 1 ) / 2 ) );

    // right most offset from current image index
    toReturn[1] = ( this.mCurrentImageOffset + Math.ceil( ( maxVisibleImages - 1 ) / 2 ) );

    //  cant go passed zero, give more to the right
    if( ( toReturn[0] ) < 0 )
    {
      toReturn[1] = this.mCurrentImageOffset + maxVisibleImages - 1;
      toReturn[0] = this.mCurrentImageOffset;
    }

    // cant go passed the end, give more to the left
    if( ( toReturn[1] ) >= this.mTotalNumberOfImages )
    {
      toReturn[0] = this.mCurrentImageOffset - ( maxVisibleImages ) + 1;
      toReturn[1] = this.mCurrentImageOffset;
    }

    // keep everything in range of 0 and this.mTotalNumberOfImages
    toReturn[0] = Math.max( toReturn[0], 0 );
    toReturn[1] = Math.min( toReturn[1], this.mTotalNumberOfImages - 1);
    return toReturn;
  };


  this.preloadImage = function( url, offset )
  {
    var preloadImage = $(new Image());

    // when the image loads populate the one the visitor sees
    var qv = this;
    var os = offset;
    preloadImage.onerror = function()
    {
      if( qv.mImageInfos[os].mediaType &&
          qv.mErrorImageUrl[ qv.mImageInfos[os].mediaType ] )
      {
        this.src = qv.mErrorImageUrl[ qv.mImageInfos[os].mediaType ];
      }
    }

    preloadImage.onload = function()
    {
      this.onload = null;
      if( qv.mImages[os].childNodes.length < 1 )
      {
        var img = $( document.createElement( 'img' ) );
        var gap = qv.GAP_SIZE;
        var dimensions = [qv.mImages[os].getWidth()-gap, qv.mImages[os].getHeight()-gap];
        var ratio = [this.width, this.height];
        var size = jshCalculateProportionalDimensions( ratio, dimensions );
        var position = [ ( ( dimensions[0] + gap - size[0] ) / 2 ), ( ( dimensions[1] + gap - size[1] ) / 2 ) ];

        img.src = this.src;
        img.style.width = ( size[0] ) + 'px';
        img.style.height = ( size[1] ) + 'px';
        img.style.position = 'relative'
        img.style.left = ( position[0] ) + 'px';
        img.style.top = ( position[1] ) + 'px';
        img.style.cursor = 'pointer';

        if( qv.mFunctionCreateImageLinkUrl )
        {
          img.onclick = function()
          {
            var url = qv.mFunctionCreateImageLinkUrl( qv.mImageInfos[os], os );
            if( url )
            {
              document.location.href = url;
            }
          }
        }

        if( qv.mShowMagnification )
        {
          img.onmouseover = function()
          {
            var gap = qv.GAP_SIZE * 2;
            var cSize = jshCalculateProportionalDimensions( ratio, [ qv.MAX_IMAGE_SIZE + gap, qv.MAX_IMAGE_SIZE + gap ] );
            var difference = [ Math.round( ( ratio[0] - size[0] ) / 2 ) - ( Math.round( ( size[0] - cSize[0] ) / 2 ) ), Math.round( ( ratio[1] - size[1] ) / 2 ) ];
            var zeroLeft = ( ( qv.mImages[os].offsetIndex - qv.mImages[qv.mImageRange[0]].offsetIndex ) * ( qv.mImages[os].getWidth() ) ) + qv.mCenterOnCurrentButtonLeft.getWidth() + Math.round( ( ratio[0] - size[0] ) / 2);
            var zeroTop =  ( 0 ) ;

            var x = ( zeroLeft + position[0] - difference[0] );
            var y = ( zeroTop + position[1] - difference[1] );

            //x = Math.min( x, ( qv.mPanel.getWidth() - cSize[0] ) );
            //x = Math.max( x, 0 );

            if( qv.mAnimate == true )
            {
              qv.mPreviewContainer.style.width = ( cSize[0] ) + 'px';
              qv.mPreviewContainer.style.height = ( cSize[1] ) + 'px';
              ElementEffects.animateElementPosition( qv.mPreviewContainer, [x, y], 55, .45, null );
            }
            else
            {
              qv.mPreviewContainer.style.width = ( cSize[0] ) + 'px';
              qv.mPreviewContainer.style.height = ( cSize[1] ) + 'px';
              qv.mPreviewContainer.style.left = ( x ) + 'px';
              qv.mPreviewContainer.style.top = ( y ) + 'px';
            }

            qv.mPreviewImage.src = img.src;
            qv.mPreviewImage.style.position = 'absolute';
            qv.mPreviewImage.style.left = ( (cSize[0] - ratio[0]) / 2 ) + 'px';
            qv.mPreviewImage.style.top = ( (cSize[1] - ratio[1]) / 2 ) + 'px';

            qv.mPreviewContainer.style.cursor = 'pointer';

            qv.mPreviewImage.onclick = img.onclick;
            qv.mPreviewContainer.title = img.title;

            qv.mPreviewContainer.show();
          };
        }

        qv.mImages[os].style.backgroundImage = '';
        qv.mImages[os].appendChild( img );

        this.onload = null;
        this.src = null;
      }
    };

    preloadImage.src = url;
  };

  this.findRefernceImage = function( offset )
  {
    var toReturn = null;
    if( offset >= 0 )
    {
      // find the first image with larger offset
      // assumes the this.mImages array is sorted by offset
      for( var i = 0; i < this.mImages.length; i++ )
      {
        if( this.mImages[i] && ( this.mImages[i].offsetIndex > offset ) )
        {
          toReturn = this.mImages[i];
          break;
        }
      }
    }

    return toReturn;
  };

  this.requestImages = function( offset )
  {
    if( offset >= 0 )
    {
      this.mRequestedImages.push( offset );
      if( this.mWaitingForImages != true )
      {
        this.mWaitingForImages = true;
        this.mAlreadyRequestedImages.push( offset );
        this.mFunctionFetchImages( offset );
      }
    }
  };

  this.setImageInfos = function( imageInfos, offset )
  {
    this.mWaitingForImages = false;
    for( var i = 0; i < this.mRequestedImages; i++ )
    {
      if( this.mRequestedImages[i] == offset )
      {
        this.mRequestedImages[i] = null;
        this.mRequestedImages = this.mRequestedImages.compact();
      }
    }

    if( imageInfos && imageInfos.length )
    {
      if( offset < 0 )
        offset = 0;

      for( var i = 0; i < imageInfos.length; i++ )
      {
        this.mImageInfos[offset + i] = imageInfos[i];
      }

      this.updateImages();
    }

    // loop through and see if we have any pending request for images
    // that have not been fetched.  return on the first one we dont have
    while( this.mRequestedImages.length > 0 )
    {
      // skip it if we already have it or if this one has already been requested
      if( ( this.mImageInfos[ this.mRequestedImages[0] ] ) ||
          ( this.mAlreadyRequestedImages.indexOf( this.mRequestedImages[0] ) >= 0 ) )
      {
        this.mRequestedImages[0] = null;
        this.mRequestedImages = this.mRequestedImages.compact();
      }
      else
      {
        this.requestImages( this.mRequestedImages[0] );
        return;
      }
    }
  };

  this.setTotalNumberOfImages = function( totalNumberOfImages )
  {
    this.mTotalNumberOfImages = totalNumberOfImages;
  };

  this.setCurrentImageOffset = function( currentImageOffset )
  {
    this.mCurrentImageOffset = parseInt( currentImageOffset );
    this.mOriginalImageOffset = parseInt( currentImageOffset );
  };

  this.setImageLinkPrefix = function( imageLinkPrefix )
  {
    this.mImageLinkPrefix = imageLinkPrefix;
  };

  this.setPlacholderImageUrl = function( placholderImageUrl )
  {
    this.mPlacholderImageUrl = placholderImageUrl;
  };

  this.setErrorImageUrls = function( errorImageUrl )
  {
    this.mErrorImageUrl = errorImageUrl;
  };

  this.setFunctionFetchImages = function( functionFetchImages )
  {
    this.mFunctionFetchImages = functionFetchImages;
  };

  this.setFunctionCreateImageLinkUrl = function( functionCreateImageLinkUrl )
  {
    this.mFunctionCreateImageLinkUrl = functionCreateImageLinkUrl;

  };

  this.setShowMagnification = function( showMagnification )
  {
    this.mShowMagnification = showMagnification;
  };

  this.setAnimate = function( animate )
  {
    this.mAnimate = animate;
  };

}





























