/******************************************
// Put this in the document header and make sure that a call to loadGallery is made onload

    <script type="text/javascript" src="js/scrollgallery.js"></script>
    <script type="text/javascript">
    var myGallery;
    function loadGallery()
    {
        myGallery = new ClassScrollGallery('myGallery');
        // alter and add pics before Build();
        myGallery.ButtonOffsetX = 20;

        var stem = "/italy/hotel/4/228114/";
        var hotel = "hotel-piemonte";
        var sI;
        for (var i = 1; i < 11; i++) {
            sI = (i < 10) ? "0"+i : i; 
            myGallery.AddPicture(stem + sI + '-' + hotel+'-t.jpg', sI);    
        }
        myGallery.Build();

    }
    </script>

// Then something like this in the body
<img id="GalleryMain" src="images/cl.gif" height="188" width="250" alt="">
    <div id="myGallery"></div>
******************************************/
if (!(document.getElementById)) { exit(); }

/*
 * make sure that div, gallery variable name match the passed parameter
 */
function ClassScrollGallery(Id)
{
    this.Id = (Id) ? Id : 'ScrollGallery';
    this.Div = document.getElementById(this.Id);
    if (!this.Div) {
        alert('You need to insert a div.'+this.Id);
        exit;
    }
    this.Pictures = new Array();

    // store preloaded main images
    this.Preloads = new Array();

    // id of target (big) image
    this.MainImgId = 'GalleryMain';


    // thumb width, height and nr of thumbs per window
    this.ThumbW = 64;
    this.ThumbH = 48;
    this.ThumbPW = 5; // extra width (padding, margin etc FOR ONE SIDE)
    this.ThumbPH = 15; // extra height (padding, margin etc FOR ONE SIDE)
    this.ThumbC = 3; // nr of thumbs per page

    this.CurrentPage = 1; 
    this.CurrentX = 0;

    // alt tags for buttons, also used to identify button in script
    this.ButtonSize = 19; // h and w in pixels
    this.ButtonAltR = 'Scroll Right for more Images';
    this.ButtonAltL = 'Scroll Left for more Images';
    this.ButtonRon = '../tlm/images/buttonron2.gif';
    this.ButtonRoff = '../tlm/images/buttonroff2.gif';
    this.ButtonLon = '../tlm/images/buttonlon2.gif';
    this.ButtonLoff = '../tlm/images/buttonloff2.gif';
    // left/right button offset if not set will auto calculate to put the button halfway over
    this.ButtonOffsetX = 0; 

    // animation 
    this.IsScrolling = false; // has a move been started
    this.Interval = false; // holds a reference to the animation interval
    this.StepC = 30; // number of steps to take
    this.Delay = 5; // interval delay in milliseconds

    // calculated values - these are set in Build so don't modify
    this.WindowW = 0;
    this.WindowH = 0;
    this.ButtonTop = 0; // how far down the buttons are
    this.StripW = 0;
    this.PageC = 0;
    this.TotalThumbW = 0; // including padding etc
    this.Step = 0; // number of pixels per leap
  
    this.Build = function()
    {
        var build = '';
        for (var i = 0; i < this.Pictures.length; i++) {
            build += this.Pictures[i].ToHtml();
        }

        this.TotalThumbW = (this.ThumbW + this.ThumbPW * 2);

        this.WindowH = this.ThumbH + this.ThumbPH * 2;
        this.WindowW = this.TotalThumbW * this.ThumbC;
        this.Step = Math.round(this.WindowW / this.StepC);
        this.StripW = this.TotalThumbW * this.Pictures.length;      
        this.PageC = Math.ceil(this.Pictures.length/this.ThumbC);

        // calculate button position.. halfway down with adjustment for image height
        this.ButtonTop = Math.round((this.WindowH - this.ButtonSize) / 2);

        var galleryDiv = document.getElementById(this.Id);
        // position it an let the buttons overflow
        galleryDiv.style.position = 'relative';
        galleryDiv.style.overflow = 'visible';

        // add the gallery first.. need the gallery in place to position the buttons
        galleryDiv.innerHTML = this.GetGallery(build);
        // then do the buttons;
        galleryDiv.innerHTML += this.GetButtons();
        this.ToggleButtons();

        // make sure the main pic is visible
        this.ChangeMainPic(document.getElementById(this.Pictures[0].Id));

        // and preload some others with a slight delay
        window.setTimeout(this.Id+'.PreloadMain()',1000);
    }

    this.GetGallery = function(ThumbsHtml)
    {
        return '<div id="GalleryWindow" style="position: relative;  overflow: hidden; width: '+this.WindowW+
        'px;height: '+ this.WindowH + 'px;margin: 0 auto;">'+
        '<div id="GalleryStrip"  style="position: absolute; left: '+this.CurrentX+'px; width: '+this.StripW+
        'px">'+ThumbsHtml+'</div></div>';
    }

    // preload on-buttons and load off buttons
    this.GetButtons = function()
    {
        new Image().src = this.ButtonLon;
        new Image().src = this.ButtonRon;

        return this.MakeButton('GalleryLArrow', this.ButtonLoff, this.ButtonAltL, -1) +
            this.MakeButton('GalleryRArrow', this.ButtonRoff, this.ButtonAltR, 1);
    }

    this.MakeButton = function (id, img, alt, changePage)
    {

        var gWin = document.getElementById('GalleryWindow');

        // windows uses text-align instead of margin auto so don't need to adjust offset
        var browserOffset = (gWin.currentStyle) ? 0 : gWin.offsetLeft;

        var buttonW = Math.floor(this.ButtonSize / 2);

        // calculate the horizontal offset of the buttons adjusting for button width
        if (this.ButtonAltR == alt) {
            var offset = this.WindowW - buttonW + browserOffset + this.ButtonOffsetX;
        } else {
            var offset = -(buttonW + this.ButtonOffsetX - browserOffset);
        }


        return '<div id="'+id+'"><img alt="'+alt+'" onmousedown="'+this.Id+'.ChangePage('+changePage+')" onmouseover="'+this.Id+
            '.ButtonOver(this)" onmouseout="'+this.Id+'.ButtonOut(this)" src="'+img+
            '" style="position: absolute; top: '+this.ButtonTop +'px; left: '+offset+'px; cursor: pointer;"></div>';

    }


    this.AddPicture = function(url, alt)
    {
        alt = alt || '';
        var i = this.Pictures.length;
        this.Pictures[i] = new this.ClassPicture(i, url, alt, this);
    }

    // choose whether to show each button
    this.ToggleButtons = function()
    {
        document.getElementById('GalleryLArrow').style.display = ( 1 == this.CurrentPage) ? 'none' : 'block';
        document.getElementById('GalleryRArrow').style.display = ( this.PageC > this.CurrentPage  ) ? 'block' : 'none';
    }

    this.ButtonOver = function(img) 
    { 
        img.src = (img.alt == this.ButtonAltR) ? this.ButtonRon : this.ButtonLon; 
    }

    this.ButtonOut = function(img) 
    { 
        img.src = (img.alt == this.ButtonAltR) ? this.ButtonRoff : this.ButtonLoff; 
    }

    /**
     * change the visible 'page' of thumbs
     *
     * @param int positive or negative number of changes to step 
     */
    this.ChangePage = function(change) 
    { 
        
        if (this.IsScrolling) { return; }

        this.IsScrolling = true;
        var newPage = this.CurrentPage + change;
      
        // only change if new page exists
        if (newPage > 0 && newPage <= this.PageC) {
            this.CurrentPage = newPage;
            // set a target position and start moving the strip towards it 
            this.TargetX = this.CurrentX - (change * this.WindowW);
            
            this.Interval = setInterval(this.Id +'.MoveStrip()', this.Delay);
            this.ToggleButtons();
            this.PreloadMain();  
        }
    }


    this.PreloadMain = function()
    {
        // count of elements to load checking for partially empty page
        var cToLoad = Math.min(this.Pictures.length, this.CurrentPage * this.ThumbC);

        // nb - new image everytime otherwise race conditions
        // from one because the main image should have already have been loaded
        var log = 'Preloading: ';
        for (var i = 1; i < cToLoad; i++) {
            if (!this.Preloads[i]) {
                log += i + ' '; 
                this.Preloads[i] = new Image();
                this.Preloads[i].src = this.Pictures[i].MainSrc();
            }
        }
        window.status = log;
    }

    /*
     * slide the strip towards target position, stopping the process when we arrive
     */
    this.MoveStrip = function()
    {
        var direction = (this.CurrentX > this.TargetX) ? -1 : 1;
        var difference = this.TargetX - this.CurrentX;
        var adjustment = this.Step * direction;
        // when we overshoot target adjust and stop
        if (Math.abs(adjustment) > Math.abs(difference)) {
            adjustment = difference;
            clearInterval(this.Interval);
            this.Interval = false;
            this.IsScrolling = false;
        }
        this.CurrentX += adjustment; 
        document.getElementById('GalleryStrip').style.left = this.CurrentX + 'px';
    }

    /*
     * @param imgob thumbnail that was clicked
     */
    this.ChangeMainPic = function(thumb)
    {
        var main = document.getElementById(this.MainImgId);

        if (!main) {
            alert('No full sized image found');
            return false;
        }
        // slice off -t to get full-sized pic
        main.src = thumb.src.replace('_t.jpg','.jpg');
        main.alt = thumb.alt;
        return true;
    }

    /**
     * @param id index of this Picture in Pictures
     * @param string path to thumbnail
     * @param string alt tag
     * @param ScrollGallery
     */
    this.ClassPicture = function(id, pic, alt, oGallery)
    {
        this.Src = pic;
        this.Id = 'Thumb'+id;
        // adjust padding to cope with side borders
        var border = 1;
        var paddingW = oGallery.ThumbPW - border;
        var pH = oGallery.ThumbPH;
        var galleryId = oGallery.Id;

        this.ToHtml = function()
        {
            return '<div style="padding: '+pH+'px '+paddingW+'px; margin:0; border: none; text-align: center; float:left; cursor:pointer;">' +
            '<img id="'+this.Id+'" style="border: '+border+ 'px solid #ccc;" src="'+this.Src+
            '" height="'+oGallery.ThumbH+'" width="'+oGallery.ThumbW+'" alt="'+alt+
            '" onclick="'+galleryId+'.ChangeMainPic(this)"></div>';
        }

        this.MainSrc = function()
        {
            return this.Src.replace('_t.jpg', '.jpg');
        }
    }
    // End ClassPicture

} // End ClassScrollGallery
