﻿/// <reference path="/CommonAssets/PhotoGalleryWidget/Src/PhotoGallery_Config.js" />


var _imgs = new Array();
var _collsCount = 1;
var _dispAreaW;
var _dispAreaH;
var _minThumOpcty = 0.5;
var _matHandlrSuffix = "";
var _pausedDiv = "_paused";
var _pageLoaded = false;
var _thereArePics = false;
var _thumbBackDrop = "__ThumbBackdrop";


var _zDisplay =     10;
var _zPictures = 20;
var _zCaptions = 25;
var _zPictCount = 27;
var _zFrames = 30;
var _zPause = 40;
var _zThumbBack = 50;
var _zThumb = 60;
var _zChasing = 70;

var _threX = 0;
var _threY = 0;

var _docReady = 0;
var _windReady = 0;

jqPG(document).ready(function() {
    _docReady = 1;

    if (_autoStart) OnDocumentReady();

});





jqPG(window).load(function() {
    _windReady = 1;

    if (_autoStart) OnWindowReady();

});



function PhotoGallery_Start(containerName) {

    if (containerName) {
        _picturesContainer = containerName;
    }

    if (_docReady > 0) {
        
        if (_docReady == 1) {
            _docReady = 2;
            OnDocumentReady();
        }

        if (_windReady > 0) {
        
            if (_windReady == 1) {
                _windReady = 2;
                OnWindowReady();
            }
        }

    }

    if (_docReady != 2 || _windReady != 2) setTimeout(function() { PhotoGallery_Start() }, 300);
    

}



function OnDocumentReady() {
    setTimeout(function() {

        /// FOR SOME REASON THE READY EVENT MAY BE TRIGGERED MORE THAN ONCE.
        /// MY BET IT'S RELATED TO SOME JAVASCRIPT ERRORS ON THE PAGE.
        if (_pageLoaded) alert('teten');
        _pageLoaded = true;

        var $chldsA = jqPG('#' + _picturesContainer).children();
        _thereArePics = $chldsA.length > 0;
        if (!_thereArePics) {
            /// NO PICTURE FOUND...
            return;
        }


        jqPG('#Pictures').hide();

        jqPG('#Display').css({ position: 'absolute', overflow: '', display: 'block',
            border: GetDebugColor(), zIndex: _zDisplay
        });
        jqPG('#Loading').css({ zIndex: 2, position: 'absolute', display: 'block', visibility: 'visible' });
        jqPG('#Loading').hide();
        jqPG('#Thumbs').css({ position: 'absolute', display: 'block', zIndex: _zThumb, border: GetDebugColor(),
            height: (_thumbSize + (_thumbPad * 2)) + 'px'
        });
        jqPG('#GoPrev').css({ position: 'absolute' });
        jqPG('#GoNext').css({ position: 'absolute' });
        jqPG('#GoNext').css({ border: GetDebugColor() });


        EvalWindowSize();


        /// ADDING THE "PAUSE" DIV
        jqPG('#Display').append('<div id="' + _pausedDiv + '" ></div>');
        jqPG('#' + _pausedDiv).css({ visibility: 'hidden', position: 'absolute' });
        jqPG('#' + _pausedDiv).bind('mouseover', HoveringOn);
        jqPG('#' + _pausedDiv).append('<img src="' + _pausedIconPath + '" id="' + _pausedDiv + '_img" alt="" />');



        /// HIDDING THE GRAY FRAMINGS COMING FROM UPPER TEMPLATES.
        jqPG(".photoholdertl").removeClass();
        jqPG(".photoholdertr").removeClass();
        jqPG(".photoholderbl").removeClass();
        jqPG(".photoholderbr").removeClass();


        ManageLoader(true);


        _matHandlrSuffix = "&seed=" + Math.random();
        if (!_isLocalHost) _matHandlrSuffix = "";


        for (var n = 0; n < $chldsA.length; n++) {
            var imgPath = jqPG($chldsA[n]).attr('rel');

            var img = new MyImage();
            img.Path = imgPath;
            img.Image = _handlerPath + "?f=" + imgPath + "&w=" + _dispAreaW +
		    "&h=" + _dispAreaH + "&m=" + _imageMode + _matHandlrSuffix;
            img.Thumb = _handlerPath + "?f=" + imgPath + "&w=" + _thumbSize + "&h=" +
		    _thumbSize + "&m=2&t=1" + _matHandlrSuffix;
            img.Index = n;
            img.Caption = jqPG($chldsA[n]).attr('rev');

            _imgs[n] = img;
        }

        if (_shuffling) DoLightShuffling();

        jqPG('#' + _picturesContainer).empty();

        _collsCount = Math.ceil(_imgs.length / _slidesPerColl);


        /// ENSURE THE CHASING_FRAME SPEED IS AT LEAST AS FAST AS THE SLIDING SPEED.
        /// 
        if (_chasingFrameSpeed >= _slideDelay) _chasingFrameSpeed = _slideDelay - 200;


        AlignPauseDiv();


        /// CREATING THE INTERVAL THAT WILL HANDLE THE CAPTION LOGIC.
        /// 
        _captionInterval = setInterval(HandleCaptionDisplay, 50);


    }, _debugFirstDelay);

}




function OnWindowReady() {

    setTimeout(function() {

        if (!_thereArePics) {
            /// THERE ARE NO PICTURES. HALTING.
            return;
        }


        jqPG(window).bind('resize', HandleWindowRezize);

        CreateThumbs();

    }, _debugFirstDelay * 2);
    
}






function EvalWindowSize(){
    /// SETTING THE DISPLAY AREA SIZE.
    ///
    if (_displayW <= 1){
        _dispAreaW = jqPG(window).width() * _displayW;
        if (_sizeSource) {
            if (jqPG('#' + _sizeSource).length == 0) {
                _sizeSource = null;
            } else {
                _dispAreaW = jqPG('#' + _sizeSource).width() * _displayW;
            }
        }
    } else {
        _dispAreaW = _displayW;
    }

    if (_displayH <= 1) {
        _dispAreaH = jqPG(window).height() * _displayH;
        if (jqPG('#' + _sizeSource).length == 0) {
            _sizeSource = null;
        } else {
            _dispAreaH = jqPG('#' + _sizeSource).height() * _displayH;
        }
    } else {
        _dispAreaH = _displayH;
    }
    
    _dispAreaW = Math.ceil(_dispAreaW);
    _dispAreaH = Math.ceil(_dispAreaH);

    jqPG('#Display').css({ width: _dispAreaW + 'px', height: _dispAreaH + 'px' });

    
    /// CREATING A WRAPPER AROUND OUR MAIN DIV IN ORDER TO "CREATE" A SPACE
    /// SO HTML ELEMENTS ARE PUSHED BELOW THE DISPLAY AREA.
    ///
    jqPG('#Display').wrap("<div id='Display_Wrapper'></div>");
    jqPG('#Display_Wrapper').css({ border: GetDebugColor(), width: _dispAreaW + 'px', height: _dispAreaH + 'px' });


    /// ENLARGING THE PICTURE CONTAINER AREA, SO ELEMENTS BELOW THE PICTURE CONTAINER WILL NOT BE
    /// OBLITERATED BY THE PICTURES, AND WILL SHOW UP RIGHT AFTER THE PICTURES AREA.
    if (_verticalSpace) {
        var disToTop = jqPG('#Display').offset().top;
        var disToTopPics = jqPG('#' + _picturesContainer).offset().top;
        var dis = _dispAreaH - (disToTopPics - disToTop);
        jqPG('#' + _picturesContainer).css({ height: dis + 'px' });
    }




    /// PULLING THE OFFSETS FOR THE PANEL WRAPPING THE WHOLE WIDGET.
    /// THIS IS REQUIRED TO PERFORM POSITIONING ADJUSTMENTS WHEN ELEMENTS
    /// ARE CONTAINED IN ABSOLUTELY POSITIONED DIVS, THE COORDINATES MAY BE RELATIVE TO
    /// THE TOP-LEFT CORNER OF THE ELEMENT INSTEAD OF THE SCREEN.
    ///
    /// STORING THIS OFFSET WILL HELP FIXING SUCH CASES.
    ////
    var oo = jqPG('#pnlBody').offset();
    _threX = oo.left;
    _threY = oo.top;

}










/*
 * THUMB RELATED METHODS
 * 
 * 
*/
function ThumbHoverOn(e){
    var index = e.data;

    var ex = _thumbSize + _thumbEnlarge;
    var o = jqPG('#tmbImg_' + index).offset();
    var l = Math.ceil(-(_thumbEnlarge / 2));
    var t = Math.ceil(-(_thumbEnlarge / 2));

    jqPG('#tmbImg_' + index).css('position', 'relative');
    jqPG('#tmbImg_' + index).animate({ opacity: 1, width: ex + 'px', height: ex + 'px',
        top: t + 'px', left: l + 'px'
    });
    
}

function ThumbHoverOut(e){
    var index = e.data;
    
    jqPG('#tmbImg_' + index).animate({ opacity: _minThumOpcty, width: _thumbSize + 'px', height: _thumbSize + 'px',
        top: '0px', left: '0px'
    });

}





function CreateThumbs(){

    for (var n = 0; n < _collsCount; n++) {
        jqPG('#Thumbs').append('<div id="Coll_' + n + '" class="CollCont" style="position:absolute; ' +
            'padding-top:' + _thumbPad + 'px"></div>');
        
        /// HIDDING ANY COLLECTION OTHER THAN THE FIRST ONE.
        if (n>0) jqPG('#Coll_' + n).hide();
        
        for(var m=0;m<_slidesPerColl;m++){
            var currIndex = ((n*_slidesPerColl)+(m+1))-1;
            if (currIndex>=_imgs.length) continue;
            var currImg = _imgs[currIndex];
            
            jqPG('#Coll_' + n).append('<span class="ThumbCont" id="tmb_' +
                currIndex + '"><img src="" alt="" style="display:none; " id="tmbImg_' + currIndex + '" /></span>');
            jqPG('#tmbImg_' + currIndex).bind('load', currIndex, ThumbLoaded );
            jqPG('#tmbImg_' + currIndex).bind('mouseover', currIndex, ThumbHoverOn );
            jqPG('#tmbImg_' + currIndex).bind('mouseout', currIndex, ThumbHoverOut );
            jqPG('#tmbImg_' + currIndex).hide();
            jqPG('#tmbImg_' + currIndex).css( { opacity: _minThumOpcty, border: GetDebugColor() } );
            
            jqPG('#tmb_' + currIndex).css( {width: _thumbSize + 'px', height: _thumbSize + 'px' } );
            
            currImg.Collection = n;
        }
        //        jqPG('#Coll_' + n).append('<div class="Clearer"></div>');
        jqPG('#Coll_' + n).css('border', GetDebugColor());
        DoLog(jqPG('#Coll_' + n).height());
    }
    

    if (_thumbnails){
        /// WE ARE USING THUMBNAILS
        LoadThumbs();
        
        CenterCollections();
        
        ChasingDivLogic();
    
    } else {
        /// WE ARE HIDING THUMBS FROM CALCULATIONS
        jqPG('#Thumbs').hide();
        jqPG('#Thumbs').css({ height: '5px' });
        
        CenterCollections();
    }

    
    LoadImagesLoop();
    
}


var _currThumbBuff = 0;
var _thumbLoadIndex = 0;
var _thumbLoadInterval;
function LoadThumbs(){

    _thumbLoadInterval=  setInterval(function(){
        
        if (_currThumbBuff < _thumbLoadBuffer){
            
            _currThumbBuff ++;
            LoadThumbByIndex(_thumbLoadIndex);
            _thumbLoadIndex ++;
            
            if (_thumbLoadIndex == _imgs.length){
                clearInterval(_thumbLoadInterval);
            }
        }
    }, 200);
}

function LoadThumbByIndex(index){
    var currImg = _imgs[index];
    if (currImg) jqPG('#tmbImg_' + index).attr({ src: currImg.Thumb });
}



function ThumbLoaded(e){

    _currThumbBuff--;

    var currImg = _imgs[e.data];
    
    var daThumb = '#tmb_' + currImg.Index;
    jqPG(daThumb).css({ cursor: "pointer", display: "" });
    
    
    /// FADING IN ONLY THOSE THUMBS IN THE FIRST COLLECTION.
    /// THE OTHER THUMBS WE DON'T SEE THEM, SO THEY SIMPLY SHOW UP.
    ///
    if (currImg.Collection == _currColl){
        jqPG('#tmbImg_' + currImg.Index).fadeIn();
    } else {
        jqPG('#tmbImg_' + currImg.Index).show();
    }
    
    
    jqPG(daThumb).bind('click', currImg.Index, EnlargeThumbBound);
}



function EnlargeThumbBound(e){
    var currImg = _imgs[e.data];
    EnlargeThumb(currImg);
}

function EnlargeThumb(currImg)
{
    /// STOPPING THE CYCLE THRU. RE ENABLES AUTOMATICALLY 
    /// WHEN A NEW IMAGE IS DISPLAYED.
    /// 
    StopCycling();
    
    /// ACT BASED ON THE IMAGE LOAD STATUS
    ///
    switch(currImg.ImageLoadStatus){
        case 2:
            /// THE IMAGE IS LOADED, THIS IS THE EASY PART.
            //DoLog('requested loaded picture: ' + currImg.Image);
            //ShowDaNicePicture(currImg);
            WaitFor(currImg);
            break;
            
        case 1:
            /// THE IMAGE IS LOADING, LET'S WAIT A LITTLE BIT.
            //DoLog('requested loading... picture: ' + currImg.Image);
            ManageLoader(true);
            WaitFor(currImg);
            break;
            
        case 0:
            /// THE IMAGE IS NOT LOADED, THIS IS THE TRICKIEST PART.
            //DoLog('requested not yet loaded picture: ' + currImg.Image);
            ManageLoader(true);
            DeBuffer(currImg);
            break;
            
    }
    
    
}

/*
 ******************************************
 ******************************************
 ******************************************
*/










/*
 * CHASING FRAME LOGIC
 * 
 * 
*/


var _lastChasedIndex;
var _chasingInterval;
function ChasingDivLogic() {
    clearInterval(_chasingInterval);
    _lastChasedIndex = null;
    
    jqPG('#ChasingDiv').remove();
    jqPG('<div id="ChasingDiv" class="FrameContainer" style="position:absolute; z-index:' + _zChasing + ';">' +
        '<div id="ChasingDivInner"></div></div>').insertAfter('#Display');
    jqPG('#ChasingDiv').hide();

    jqPG('#ChasingDivInner').css({ backgroundColor: 'yellow', opacity: 0,
        width: _thumbSize + 'px', height: _thumbSize + 'px'
    });

    _chasingInterval = setInterval(function() {

        var ix = _imgs[_currSlide].Index;

        var offst = jqPG('#tmbImg_' + ix).offset();

        var w = jqPG('#tmbImg_' + ix).width();

        if (!offst) return;

        if (offst.left <= 0) return;

        if (ix == _lastChasedIndex) return;

        if (_lastChasedIndex == null) {

            jqPG('#ChasingDiv').css({ width: _thumbSize + 'px', height: _thumbSize + 'px',
                left: (offst.left - _chasingFrameXOffst - _threX) + 'px',
                top: (offst.top - _chasingFrameXOffst - _threY) + 'px'
            });
            jqPG('#ChasingDiv').fadeIn(2000);

        } else {

            /// WE NEED THIS DELTA IN CASE THE THUMB SIZE HAS BEEN ENLARGED WITH A THUMB HOVER.
            /// WE WANT TO NEUTRALIZE THIS "OVERSIZE".
            var deltha = (w - _thumbSize) / 2;

            jqPG('#ChasingDiv').animate({ left: (offst.left - _chasingFrameXOffst + deltha - _threX) + 'px',
                top: (offst.top - _chasingFrameXOffst + deltha - _threY) + 'px'
            }, _chasingFrameSpeed, "swing");
        }

        _lastChasedIndex = ix;


    }, 200);

}

/*
 ******************************************
 ******************************************
 ******************************************
*/









/*
 * SLIDE SHOW LOGIC
 * 
 * 
*/
var _currSlide = 0;
var _slideInterval;

function StartPlaying(){
    /// CALLED WHEN THE CURRENT (OR FIRST) IMAGE IS LOADED.
    var currImg = _imgs[_currSlide];
    
    //DoLog("START PLAYING MAN");
    ShowDaNicePicture(currImg);
    
    jqPG('#GoNext').bind('click', GoForward);
    jqPG('#GoPrev').bind('click', GoBackwards);
    
    jqPG('#Display').bind('mouseover', HoveringOn );
    jqPG('#Display').bind('mouseout', HoveringOut );

}

function CycleThru(){

    if (!_autoAdvance) return;
    
    clearTimeout(_slideInterval);
    _slideInterval = setTimeout(function(){
        
        _currSlide++;
        
        EstimateShuffling( _currSlide );
        
        if (_currSlide==_imgs.length)_currSlide=0;

        var currImg = _imgs[_currSlide];
        //DoLog('trying to display ' + currImg.Image);
        EnlargeThumb(currImg);
        
        
    }, _slideDelay);
    
}

function StopCycling(){
    clearTimeout(_slideInterval);
}


var _hovrIsOn = false;
function HoveringOn() {
    _hovrIsOn = true;
    
    /// WILL EXIT IF "PAUSE" IS NOT ENABLED OR NOT "AUTO ADVANCING"
    if (!_enablePause || !_autoAdvance) return;

    //DoLog("DISABLING CYCLE THRU");
    jqPG('#' + _pausedDiv ).css('visibility', 'visible');
    StopCycling();
}

function HoveringOut() {
    _hovrIsOn = false;

    /// WILL EXIT IF "PAUSE" IS NOT ENABLED OR NOT "AUTO ADVANCING"
    if (!_enablePause || !_autoAdvance) return;

    var currImage = _imgs[_currSlide];
    if (currImage.ImageLoadStatus == 2) {
        //DoLog("ENABLING CYCLE THRU");
        jqPG('#' + _pausedDiv).css('visibility', 'hidden');
        CycleThru();
    }
}


function GoForward(){
    SlideOffset(1);
}

function GoBackwards(){
    SlideOffset(-1);
}

var _sliding = false;
function SlideOffset(offst){

    if (_sliding) return;
    _sliding = true;
    
    /// MAINTAIN THINGS BUSY FOR A WHILE
    ///
    setTimeout(function(){ _sliding = false; }, _slideFadeSpeed * 1.1);

    var _next = _currSlide + offst;
    
    EstimateShuffling( _next );
    
    if (_next==_imgs.length)_next = 0;
    if (_next<0)_next = _imgs.length - 1;
    var currImg = _imgs[_next];
    EnlargeThumb(currImg);
}


var _alignDivTimeout;
function AlignPauseDiv() {

    if (!_alignDivTimeout) {
        _alignDivTimeout = setInterval(AlignPauseDiv, 100);
        return;
    }
    

    if (jqPG('#Container_' + _imgCount).width() < 10) return;


    var o = jqPG('#Container_' + _imgCount).offset();

    var w = jqPG('#' + _pausedDiv + '_img').width();
    var h = jqPG('#' + _pausedDiv + '_img').height();
    var x = Math.ceil((_dispAreaW - w) / 2);
    var y = Math.ceil((_dispAreaH - h) / 2);



    /// CALCULATING THE DIFFERENT DIV ALIGNMENT, SUCH AS UPPER RIGHT, LOWER LEFT, CENTER, AND SO ON...
    ///
    var ll; var tt;

    if (_pauseDivLocation == 1) {
        ll = o.left;
        oo = o.top;
    } else if (_pauseDivLocation == 2) {
        ll = jqPG('#Container_' + _imgCount).width() + o.left - w - _pauseDivPadding * 2;
        oo = o.top;
    } else if (_pauseDivLocation == 3) {
        ll = o.left;
        oo = jqPG('#Container_' + _imgCount).height() + o.top - h - _pauseDivPadding * 2;
    } else if (_pauseDivLocation == 4) {
        ll = jqPG('#Container_' + _imgCount).width() + o.left - w - _pauseDivPadding * 2;
        oo = jqPG('#Container_' + _imgCount).height() + o.top - h - _pauseDivPadding * 2;
    } else if (_pauseDivLocation == 5) {
        var half = jqPG('#Container_' + _imgCount).width() / 2;
        half += o.left;
        var pauseW = (w + (_pauseDivPadding * 2)) / 2;
        ll = Math.ceil(half - pauseW);

        half = jqPG('#Container_' + _imgCount).height() / 2;
        half += o.top;
        var pauseH = (h + (_pauseDivPadding * 2)) / 2;

        oo = Math.ceil(half - pauseH);
    }


    jqPG('#' + _pausedDiv).css({ opacity: '0.3', padding: _pauseDivPadding + 'px', zIndex: _zPause,
        top: oo - _threY + 'px', left: ll - _threX + 'px', border: GetDebugColor()
    });

}


/*
 ******************************************
 ******************************************
 ******************************************
*/







/*
 * DISPLAYING IMAGES BASED ON THEIR LOAD STATUS
 * 
 * 
*/

var _waitForTimeout;

function DeBuffer(currImg){

    clearTimeout(_waitForTimeout);
    clearInterval(_waitForTimeout);

    //DoLog('DEBUFFERING FOR ' + currImg.Index);
    _currBufferIndex = currImg.Index

    _waitForTimeout = setInterval(function(){ 
        if (currImg.ImageLoadStatus == 2){
            clearInterval(_waitForTimeout);
            ShowDaNicePicture(currImg);
            //DoLog("De Buffered Image Loaded! " + currImg.Image);
        }
    }, 200);

}




function WaitFor(currImg) {
    clearTimeout(_waitForTimeout);
    clearInterval(_waitForTimeout);
    if (currImg.ImageLoadStatus == 2){  
        /// LOADED !
        //DoLog("Image Loaded! " + currImg.Image);
        ShowDaNicePicture(currImg);
    } else {
        /// KEEP WAITING
        _waitForTimeout = setTimeout(function(){ WaitFor(currImg); }, 200);
    }
}


var _imgCount = 0;
function ShowDaNicePicture(currImg){

    ManageLoader(false);

    _imgCount ++;


    /// CREATING THE CONTAINER FOR THE REQUESTED IMAGE.
    ///
    jqPG('#Display').append('<img src="" alt="" id="Container_' + _imgCount +
        '" style="position:absolute; z-index:' + _zPictures + '"></img>');

    /// DEALING WITH THE NEXT/PREV COLLECTION 
    /// BASED ON THE CURRENT IMAGE COLLECTION INDEX.
    HandleCollection(currImg);

    
    _currSlide = currImg.Index;

    
    jqPG('#Container_' + _imgCount ).hide();
    jqPG('#Container_' + _imgCount ).bind('load', function(){ ShowMustGoOn() });
    jqPG('#Container_' + _imgCount ).attr( { src: currImg.Image } );

        
}


/// WE NEEDED TO SEPARATE THIS PART OF THE 'ShowDaNicePicture' AND BIND IT
/// TO THE 'LOAD' EVENT OF THE CONTAINER IMAGE.
/// THIS WAS DUE TO SOME BROWSERS WHICH ARE NOT "CACHING" THE IMAGES AS WE EXPECTED,
/// SO WE NEED TO WAIT FOR IT TO LOAD.
function ShowMustGoOn(){

    /// CENTERING THE IMAGE IN ITS DISPLAY AREA.
    CenteringLogic('Container_' + _imgCount);

    jqPG('#Container_' + _imgCount ).fadeIn( _slideFadeSpeed );

    CreateFramings( _imgCount );


    PicturePositionLogic();


    if (_imgCount>1){
        jqPG('#Container_' + (_imgCount - 1) ).fadeOut( _slideFadeSpeed , function(){ jqPG(this).remove() } );
        ExtinguishFramings ( _imgCount - 1 );
    }
    
    CycleThru();

}


function CreateFramings(imgCount) {

    /// Z-INDEX UPDATING OF THE THUMBS CONTAINER TO ALWAYS KEEP ON TOP OF PICTURES.
    ///
    jqPG('#' + _thumbBackDrop).css({ zIndex: _zThumbBack });
    jqPG('#Thumbs').css({ zIndex: _zThumb });
    jqPG('#ChasingDiv').css({ zIndex: _zChasing });


    if (_framingsImageName == "") return;


    for (var n = 0; n < 4; n++) {
        var i = _framingsImageName.replace('#', n);

        var str = '<div id="fmgs_' + imgCount + '_' + n + '" >' +
        '<img src="' + i + '" alt="" /></div>';

        jqPG('#Display').append(str);

        jqPG('#fmgs_' + imgCount + '_' + n).css({ position: 'absolute', zIndex: _zFrames, border: GetDebugColor(),
            width: _photoHolderSize + 'px', height: _photoHolderSize + 'px'
        });

    }
    jqPG('#fmgs_' + imgCount).fadeIn();

    var obj = '#Container_' + imgCount;





    var tp = jqPG(obj).offset().top - _photoHolderOffset - _threY;
    var btm = jqPG(obj).offset().top + jqPG(obj).height() - _photoHolderSize + _photoHolderOffset - _threY; // + jqPG('#Thumbs').height();
    var lft = jqPG(obj).offset().left - _photoHolderOffset - _threX;
    var rgt = jqPG(obj).offset().left + jqPG(obj).width() - _photoHolderSize + _photoHolderOffset - _threX;
    jqPG('#fmgs_' + imgCount + '_0').css({ top: tp + 'px', left: lft + 'px' });
    jqPG('#fmgs_' + imgCount + '_1').css({ top: tp + 'px', left: rgt + 'px' });
    jqPG('#fmgs_' + imgCount + '_2').css({ top: btm + 'px', left: lft + 'px' });
    jqPG('#fmgs_' + imgCount + '_3').css({ top: btm + 'px', left: rgt + 'px' });

    for (var n = 0; n < 4; n++) {
        jqPG('#fmgs_' + imgCount + '_' + n).fadeIn();
    }


}











/*
* CAPTION RELATED LOGIC.
* 
* 
*/

var _captionDivCreated = false;
var _captionInterval;
var _captionLocked = false;

/// SHOW CAPTION WILL LOCK ON THE CAPTION UNTIL TOLD OTHERWISE.
///
function LockCaption() {
    _captionLocked = true;
}


/// WILL UNLOCK THE CAPTION, RESUMING THE CONFIGURED BEHAVIOR .
///
function UnlockCaption() {
    _captionLocked = false;
}


function HandleCaptionDisplay() {

    var hoverIsOn = _hovrIsOn;
    var captionMode = _captionMode;


    /// CHECKING IF THE CAPTION IS LOCKED.
    /// IF TRUE, THE CAPTION SHOWS UP ALL THE TIME.
    /// 
    if (_captionLocked) captionMode = 1;
    


    /// MAKING A FIRST SET OF CHECKS TO AVOID UNNECESSARY FURTHER PROCESSING.
    ///
    if (!hoverIsOn && captionMode == 2 && !_captionDivCreated) return;

    if (captionMode == 0 && !_captionDivCreated) return;


    var destroy = false;

    /// GETTING THE CURRENTLY DISPLAYED IMAGE COORDINATES.
    var off = jqPG('#Container_' + _imgCount).offset();
    if (!off)return;
    
    var tp = off.top - _threY;
    var lft = off.left - _threX;

    /// GETTING THE CURRENTLY DISPLAYED IMAGE SIZE.
    var w = jqPG('#Container_' + _imgCount).width();
    var h = jqPG('#Container_' + _imgCount).height();


    /// GETTING THE CAPTION FOR THE CURRENT IMAGE.
    var caption = _imgs[_currSlide].Caption;




    var captPadd = _captionPadding;

    /// CREATING THE CAPTION DIV, IF IT DOESN'T ALREADY EXISTS.
    ///
    if (!_captionDivCreated && captionMode > 0) {
        var hlpr = "";
        if (_captionBackClass == "") hlpr = "background-color:black;";
        jqPG('#Display').append('<div id="_Captions_Back" class="' + _captionBackClass + '" style="' + hlpr +
            'position:absolute; z-index:' + _zCaptions + '">&nbsp;</div>');

        hlpr = "";
        if (_captionFrontClass == "") hlpr = "font-family:Times New Roman; font-size:19px; color:White;";
        jqPG('#Display').append('<div id="_Captions_Text" class="' + _captionFrontClass + '" ' +
            'style="' + hlpr + 'cursor:arrow; white-space:nowrap; overflow:hidden; ' +
            'position:absolute; z-index:' +
            (_zCaptions + 1) + '"></div>');
        _captionDivCreated = true;
        DoLog("created...");
    } else {

        if (captionMode == 0) destroy = true;

    }

    
    if (!hoverIsOn && captionMode == 2) destroy = true;


    if (destroy) {
        /// WILL REMOVE THE CAPTION LAYERS IF CAPTION IS TURNED OFF AND
        /// THE CAPTIONS LAYER WERE ALREADY CREATED.
        _captionDivCreated = false;
        jqPG('#_Captions_Back').remove();
        jqPG('#_Captions_Text').remove();
        DoLog("destroyed...");
    }


    /// GOING AWAY IF CAPTIONS ARE OFF OR A DESTROY WAS REQUESTED.
    if (captionMode == 0 || destroy) return;


    jqPG('#_Captions_Text').text("&nbsp;");
    jqPG('#_Captions_Text').removeAttr("alt");


    /// ADJUSTING THE POSITION
    jqPG('#_Captions_Text').css({ border: GetDebugColor(), width: w - (captPadd * 2), top: tp - captPadd,
        left: lft - (captPadd / 2), padding: captPadd
    });



    var captionHeight = jqPG('#_Captions_Text').outerHeight();

    jqPG('#_Captions_Back').css({ border: GetDebugColor(), width: w, top: tp, left: lft, height: captionHeight });

    if (_captionBackClass == "") jqPG('#_Captions_Back').css({ opacity: 0.3 });


    var adjustedTop = tp + _captionMargin;


    ////////////////////////////// 
    /// HANDLING THE CAPTION-HEIGHT LOGIC.
    /// 
    var _ch = _captionHeight;
    var _workHeight = 0;
    if (_ch >= 0.01 && _ch <= 1) {
        _workHeight = _ch * h;
    } else if (_ch > 1) {
        _workHeight = _ch;
    }

    if (_workHeight > 0) {
        jqPG('#_Captions_Back').css('height', _workHeight);
    }

    if (_workHeight == 0) _workHeight = captionHeight;

    ///
    ////////////////////////////// 



    /// MAKING SOME CALCS IF THE CAPTION IS BOTTOM POSITIONED
    if (_captionPos != 1) {
        adjustedTop = h - _workHeight - _captionMargin + _thumbVOffset;
        if (_thumbnails) adjustedTop -= jqPG('#Thumbs').height() + _captionMargin;
    }

    jqPG('#_Captions_Back').css({ top: adjustedTop });


    /// TWEAKING THE CAPTION TEXT POSITION SO IT'S ALIGNED IN RELATION
    /// TO THE CONTAINING RECTANGLE.
    var alignedPos = adjustedTop;
    if (_captionTextVAlign == 2) alignedPos = adjustedTop + (_workHeight - captionHeight) / 2;
    if (_captionTextVAlign == 3) alignedPos = adjustedTop + _workHeight - captionHeight;
    jqPG('#_Captions_Text').css({ top: alignedPos });


    jqPG('#_Captions_Text').text(caption);
    jqPG('#_Captions_Text').attr('alt', caption);


}




/*
******************************************
******************************************
******************************************
*/












var _pictureCountDiv = false;
function PicturePositionLogic() {

    /// GETTING THE CURRENTLY DISPLAYED IMAGE COORDINATES.
    var tp = jqPG('#Display').offset().top - _threY;
    var lft = jqPG('#Display').offset().left - _threX;

    /// GETTING THE CURRENTLY DISPLAYED IMAGE SIZE.
    var w = jqPG('#Display').width();
    var h = jqPG('#Display').height();

    var fixW = _pictCounterWidth;

    if (fixW <= 1) fixW = w * _pictCounterWidth;

    var deltha = w - fixW;
    w = fixW;
    lft = lft + (deltha / 2);


    var countrPadd = _pictCounterPadding;


    if (!_pictureCountDiv && _pictCounter) {
        var hlpr = "";
        if (_pictCounterBackClass == "") hlpr = "background-color:black;";
        jqPG('#Display').append('<div id="_PictCounter_Back" class="' + _pictCounterBackClass + '" style="' + hlpr +
            'position:absolute; z-index:' + _zPictCount + '">&nbsp;</div>');

        hlpr = "";
        if (_pictCounterFrontClass == "") hlpr = "font-family:Times New Roman; font-size:19px; color:White;";
        jqPG('#Display').append('<div id="_PictCounter_Text" class="' + _pictCounterFrontClass + '" ' +
            'style="' + hlpr + 'cursor:arrow; white-space:nowrap; overflow:hidden; ' +
            'position:absolute; z-index:' +
            (_zPictCount + 1) + '"></div>');
        _pictureCountDiv = true;
    } else {

        if (!_pictCounter) {
            _pictureCountDiv = false;
            jqPG('#_PictCounter_Back').remove();
            jqPG('#_PictCounter_Text').remove();
            DoLog("destroyed...");
        }

    }


    /// RETURNING IF CAPTIONS ARE OFF.
    if (!_pictCounter) return;

    jqPG('#_PictCounter_Text').text("&nbsp;");
    jqPG('#_PictCounter_Text').removeAttr("alt");

    jqPG('#_PictCounter_Back').css({ width: w, left: lft, top: tp });
    jqPG('#_PictCounter_Text').css({ width: w, left: lft, top: tp });


    /// ADJUSTING THE POSITION
    jqPG('#_PictCounter_Text').css({ border: GetDebugColor(), width: w - (countrPadd * 2), top: tp - countrPadd,
        left: lft - (countrPadd / 2), padding: countrPadd
    });

    var pictCounterHeight = jqPG('#_PictCounter_Text').outerHeight();

    jqPG('#_PictCounter_Back').css({ border: GetDebugColor(), width: w, top: tp, left: lft, height: pictCounterHeight });


    if (_pictCounterFrontClass == "") jqPG('#_PictCounter_Back').css({ opacity: 0.3 });


    var adjustedTop = tp - pictCounterHeight - _pictCounterMargin;


    /// MAKING SOME CALCS IF THE CAPTION IS BOTTOM POSITIONED
    if (_pictCounterPos != 1) {
        adjustedTop = h + _pictCounterMargin;
    }

    jqPG('#_PictCounter_Text').css({ top: adjustedTop });
    jqPG('#_PictCounter_Back').css({ top: adjustedTop });



    var daText = _pictText.replace('#0#', (_currSlide + 1)).replace('#1#', _imgs.length);

    jqPG('#_PictCounter_Text').text(daText);
    jqPG('#_PictCounter_Text').attr('alt', daText);

}





function ExtinguishFramings( imgCount ){
    for(var n=0;n<4;n++){
        jqPG('#fmgs_' + imgCount + '_' + n).fadeOut(function(){ jqPG(this).remove(); });
    }
}



/// This Method will center a picture inside the Display-Area,
/// vertically and horizontally, unless the user configures it otherwise.
///
function CenteringLogic(imgID) {

    var w = jqPG('#'+imgID).width();
    var h = jqPG('#'+imgID).height();
    
    var playAreaW = jqPG('#Display').width();
    var playAreaH = jqPG('#Display').height();
 
    var x = (playAreaW - w) / 2;
    var y = (playAreaH - h) / 2;

    /// if picture valign = top:
    if (_pictVAlign == 1) y = 0 + _pictVPad;
    
    /// if picture valign = bottom:
    if (_pictVAlign == 3) y = playAreaH - h - _pictVPad;

    jqPG('#'+imgID).css( { left: x, top: y } );
}


/*
 ******************************************
 ******************************************
 ******************************************
*/







/*
 * IMAGE PRELOADING LOGIC WITH BUFFERED CAPABILITIES.
 * 
 * 
*/

var _currBufferIndex = 0;
var _currLoadBuffer = 0;
var _loadCount = 0;
var _loopInterval;

function LoadImagesLoop(){

    _loopInterval = setInterval(function(){
        
        if (_currLoadBuffer < _loadBuffer){
            
            if (_currBufferIndex >= _imgs.length) _currBufferIndex = 0;
            //DoLog("Pre Loading " +_currBufferIndex);
            
            if (LoadImagesByIndex(_currBufferIndex) == false) {
                _loadCount ++;
            } else {
                _loadCount = 0;
            }
            _currBufferIndex ++;
            
            if (_loadCount == _imgs.length){
                clearInterval(_loopInterval);
            }
        }
    }, 200);

}


function LoadImagesByIndex(index){

    var currImage = _imgs[index];
    if (currImage == null) return;
    if (currImage.ImageLoadStatus != 0) return false;

    //DoLog('loading... ' + index + " ... src= " + currImage.Image);

    _currLoadBuffer ++;

    currImage.ImageLoadStatus = 1;

    jqPG('#Pictures').append('<img src="" alt="" id="img_' + index + '" style="width:30px; height:30px;"></img>');
    jqPG('#img_' + index).bind('load', currImage, DoneLoading );
    jqPG('#img_' + index).attr( { src: _imgs[index].Image } );
    
    
    return true;
}


function DoneLoading(e){
    var currImage = e.data;
    currImage.ImageLoadStatus = 2;
    
    _currLoadBuffer --;
    
    if (currImage.Index == _imgs[_currSlide].Index ) StartPlaying();
}


/*
 ******************************************
 ******************************************
 ******************************************
*/





/*
 * COLLECTION RELATED METHODS:
 * 
 * 
*/
var _currColl = 0;

function HandleCollection(currImg){
    
    var nextColl = currImg.Collection;
    
    if (nextColl  != _currColl){
        //DoLog('move to collection ' + nextColl );
        
        MoveToCollection(nextColl);
        _currColl = nextColl;
    }
}

function MoveToCollection(collIndex){
    HideCollection(_currColl);
    ShowCollection(collIndex);
}

function HideCollection(collIndex){
    //$('#Coll_' + collIndex).css( { display: 'none' } );
    jqPG('#Coll_' + collIndex).fadeOut( _collFadeSpeed );
}

function ShowCollection(collIndex){
    //jqPG('#Coll_' + collIndex).css( { display: 'block' } );
    jqPG('#Coll_' + collIndex).fadeIn( _collFadeSpeed );
}


function CenterCollections() {

    if (!_thumbnails) return;

    jqPG('#Thumbs').css({ width: _dispAreaW + 'px' });

    for (var n = 0; n < _collsCount; n++) {
        var w = _dispAreaW;
        var x = (_dispAreaW - jqPG('#Coll_' + n).width()) / 2;
        jqPG('#Coll_' + n).css({ left: x + 'px' });

        if (n == 0) {
            w = jqPG('#Coll_' + n).width();
            x = (_dispAreaW - w) / 2;

            /// CENTERING - ALIGNING ALL THE ELEMENTS.
            ///

            var prevWidth = jqPG('#GoPrev').width();

            var alignPrev = Math.ceil(((_thumbSize + (_thumbPad * 2)) - jqPG('#GoPrev').height()) / 2);
            jqPG('#GoPrev').css({ left: x - prevWidth - _prevNextOffst, display: 'block', border: '',
                border: GetDebugColor(), top: alignPrev
            });

            var alignNext = Math.ceil(((_thumbSize + (_thumbPad * 2)) - jqPG('#GoNext').height()) / 2);
            jqPG('#GoNext').css({ left: x + w + _prevNextOffst, display: 'block', border: '',
                border: GetDebugColor(), top: alignNext
            });

            jqPG('#Thumbs').css({ top: (jqPG('#Display').offset().top + _thumbVOffset + _dispAreaH - _threY) + 'px' });

            var yy = jqPG('#Thumbs').outerHeight(true) + jqPG('#Display').outerHeight(true);

        }

    }

    var t = jqPG('#Thumbs').offset().top + _thumbVerticalOffset - _threY;
    var l = jqPG('#Thumbs').offset().left - _threX;

    jqPG('#Thumbs').css({ top: t + 'px' });


    /// CREATING A BACK-DROP, WHICH IS SIMPLY A RECTANGLE OF THE "THUMBNAILER" SIZE.
    /// THIS CAN BE TRANSPARENT, OR HAVE A SEMI TRANSPARENT COLOR TO ACHIEVE A NICER LOOK.
    ///
    jqPG('#' + _thumbBackDrop).remove();
    jqPG('#Display').append('<div id="' + _thumbBackDrop + '" class="ThumbBackdrop" style="position:absolute; z-index: ' +
        _zThumbBack + ';"></div>');
    jqPG('#' + _thumbBackDrop).css({ width: jqPG('#Thumbs').width() + 'px', height: jqPG('#Thumbs').height() + 'px',
        left: l + 'px', top: t + 'px'
    });


}

var _canShuffle = true;
function EstimateShuffling( currSlide ){
    if (_shuffling && _canShuffle){
        if (currSlide >= _imgs.length ){
            _canShuffle = false;
            _currSlide = 0;
            DoShuffling();
            setTimeout(function(){ _canShuffle = true; } , 1000);
        }
    }
}

function DoLightShuffling(){
    Shuffle( true );
}

function DoShuffling(){
    Shuffle( false );
}

function Shuffle( isLight ){

    var cloneImgs = _imgs;
    cloneImgs = fisherYates(cloneImgs);
    var _coll = 0;
    
    for(var n = 0; n < cloneImgs.length; n++){
        
        if (!isLight) {
            /// MOVE THUMBS AROUND.
            jqPG('#tmbImg_' + cloneImgs[n].Index ).appendTo( '#tmb_' + n );
            jqPG('#tmbImg_' + cloneImgs[n].Index ).attr( { rel: n } );
        }

        _imgs[n].Image = cloneImgs[n].Image;
        _imgs[n].Thumb = cloneImgs[n].Thumb;
        _imgs[n].ImageLoadStatus = cloneImgs[n].ImageLoadStatus;
        _imgs[n].ThumbLoaded = cloneImgs[n].ThumbLoaded;
        _imgs[n].Path = cloneImgs[n].Path;
        _imgs[n].Index = n;
        _imgs[n].Collection = Math.floor(n / _slidesPerColl);
        
    }
    
    for(var n = 0; n < cloneImgs.length; n++){
        jqPG('#tmbImg_' + _imgs[n].Index ).attr( { id: 'tmbImg_' + jqPG('#tmbImg_' + _imgs[n].Index ).attr('rel'), rel: '' } );
    }    

}

function fisherYates ( images ) {
  var i = images.length;
  if ( i == 0 ) return false;
  while ( --i ) {
     var j = Math.floor( Math.random() * ( i + 1 ) );
     var tempi = images[i];
     var tempj = images[j];
     images[i] = tempj;
     images[j] = tempi;
   }
   return images;
}
/*
 ******************************************
 ******************************************
 ******************************************
*/



function ManageLoader(showIt){
    var coords = jqPG('#Display').offset();
    var x = coords.left;
    var y = coords.top;
    var w = jqPG('#Display').width();
    var h = jqPG('#Display').height();
    
    var ww = jqPG('#Loading').width();
    var hh = jqPG('#Loading').height();
    
    var xx = x + ( ( w - ww) / 2 );
    var yy = y + ( ( h - hh ) / 2 );

    jqPG('#Loading').css({ left: xx - _threX + 'px', top: yy - _threY + 'px' });
    
    if (showIt){
        jqPG('#Loading').fadeIn(300);
    } else {
        jqPG('#Loading').fadeOut(300);
    }
}



var _resizing = false;
var _resizeTimeout;
function HandleWindowRezize(){ 
    if (_resizing)return;

    clearTimeout(_resizeTimeout);    
    _resizeTimeout = setTimeout(DoHandleWindowRezize, 500);

}

function DoHandleWindowRezize(){

    _resizing = true;

    jqPG('#GoNext').unbind();
    jqPG('#GoPrev').unbind();
    jqPG('#Display').unbind();
    
    EvalWindowSize();
    
    ExtinguishFramings( _imgCount );
    
    CenterCollections();

    jqPG('#' + _pausedDiv).css('visibility', 'hidden');
    
    ManageLoader(true);
    
    
    CenteringLogic('Container_' + _imgCount);
    jqPG('#Container_' + _imgCount ).fadeOut( _slideFadeSpeed , function(){ jqPG(this).remove() } );
    
    
    clearInterval(_loopInterval);   
    clearTimeout(_slideInterval);
    
    for(var n=0;n<_imgs.length;n++){
        _imgs[n].Image = _handlerPath + "?f=" + _imgs[n].Path + "&w=" + _dispAreaW + 
	    "&h=" + _dispAreaH + "&m=" + _imageMode + _matHandlrSuffix
	    _imgs[n].ImageLoadStatus = 0;
    }
    
    _currLoadBuffer = 0;
    _currBufferIndex = _imgs[_currSlide].Index;
    _loadCount = 0;
    
    jqPG('#Pictures').empty();
    
    LoadImagesLoop();
    
    ChasingDivLogic();
    
    
    /// PREVENTING THE RESIZING FOR THE NEXT 2 SECONDS.
    setTimeout(function(){ _resizing = false; }, 2000);
    
}





function MyImage() {
    this.Image = "";
    this.Thumb = "";
    this.Index = 0;
    this.Collection = 0;
    this.ImageLoadStatus = 0;     //0=NotLoaded  1=Loading   2=Loaded
    this.ThumbLoaded = false;
    this.Path = "";
    this.Caption = "";
}


var _myLogger = false;
var _myLoggerCount = 0;
function DoLog(msg){
    if (_isLocalHost) {
        if (!_myLogger){
            jqPG('#Display').prepend('<div style="width:99%; position:absolute; z-index:500; ">' +
                '<div style="width:200px; border:2px solid green; float:right;" id="_logConsole"></div></div>');
            _myLogger = true;
        }
        jqPG('#_logConsole').prepend('<div class="_logRow">' + (_myLoggerCount++) + " > " + msg + '</div>');
    }
}



var _done = false;
function GetDebugColor() {

    if (!_isLocalHost) return "";

    var myColors = ["Red", "Blue", "Green", "Orange", "Maroon"];
    var ix = Math.ceil(Math.random() * myColors.length - 1);

    return "2px solid " + myColors[ix];
}



