/*****************************************************************************
    slideshow for gots main page

    (c) 2008 arkadiusz juszczyk <arkadiusz@waehrendwahr.de>

    must be initialized with the dom image element of the slideshow image and
    array of image data, see initSlideshow().

    the following php function generate and print code the necessary file
    information:
    
        function print_image_list($directory) {
            $files = array();
            if( $dir_handle = @opendir($directory) ) {
                print( "[\n" );
                $delim = "";
                while(false !== ($file_name = readdir($dir_handle))) {
                    if ($file_name != "." && $file_name != "..") {
                        $file_info = stat($directory. "/" . $file_name);
                        print( $delim . "{ ".
                            "'name': '" .  addslashes($directory . "/" . $file_name) . "', " .
                            "'title': '" . addslashes(substr($file_name, 0, strpos($file_name, "."))) . "', ".
                            "'time': " . $image['time'] . "}" 
                        );
                        $delim = ",\n";
                    }
                }
                print( "\n]" );
                closedir($dir_handle);
            }
        }

*****************************************************************************/


/* current sort setting, possible settings "name", "time", "random" */
var slideshowSort = "date";

/* current sort setting, possible settings "asc", "desc" */
var slideshowSortDir = "descending";

/* slideshow start setting: if true randomize starting point, else start at
 first image according to sort */
var slideshowRandomStart = true;

/* current speed setting, in seconds */
var slideshowSpeed = 6;


/* slideshow div. will generate image tag, map, and overlay divs here. must be
 pre-styled with slideshow image size. */
var slideshowDiv = null;

/* slideshow image element */
var slideshowImage = null;

/* array with image data. will be sorted in the client */
var slideshowArray = null;

/* timeout handle */
var slideshowTimer = null;

/* current image, index into the sorted array */
var slideshowIndex = 0;

/* flag, show image list (mostly for debugging) */
var showImageList = false;


/**
    initialize slideshow.

    load cookie settings.
    apply loaded settings or default settings to image array.
    setup dom elements. 
    setup timer
 

    @param  sDiv    slideshow-div, must contain css size declaration
    @param  sImages images info as described above
 */
function slideshowInit(sDiv, sImages) {
    slideshowDiv = sDiv;
    slideshowDiv.absolutize();
    slideshowArray = sImages;

    var width = slideshowDiv.getWidth();
    var height = slideshowDiv.getHeight();

    // load settings from cookie
    slideshowLoad();
    // initial sort of image array
    slideshowApplySort();
    slideshowIndex = 0;
    
    // create image element with initial image
    slideshowImage = new Element('img', 
        { src: slideshowArray[slideshowIndex].name });
    slideshowDiv.appendChild(slideshowImage);

    // create controls div
    slideshowControls = new Element('div');
    slideshowControls.setStyle({
        'position': 'absolute',
        'width': width+"px",
        'height': height+"px",
        'left': "0px",
        'top': "0px",
        'overflow': 'hidden'
    } );
    slideshowDiv.appendChild(slideshowControls);

    // manual navigation display arrows, visual must be defined via css classes
    // "slideshowLeft" and "slideshowRight"
    sCtrlDispLeft = new Element('div', {id:'sCtrlDispLeft'});
    sCtrlDispLeft.addClassName('slideshowLeft');
    sCtrlDispLeft.setStyle({
        'position': 'absolute',
        'left': "0px",
        'top': "0px",
        'display': 'none'
    });
//    sCtrlDispLeft.setOpacity(.5);
    slideshowControls.appendChild(sCtrlDispLeft);
    
    sCtrlDispRight = new Element('div', {id:'sCtrlDispRight'});
    sCtrlDispRight.addClassName('slideshowRight');
    sCtrlDispRight.setStyle({
        'position': 'absolute',
        'left': (width-sCtrlDispLeft.getWidth())+"px",
        'top': "0px",
        'display': 'none'
    });
//    sCtrlDispRight.setOpacity(.5);
    slideshowControls.appendChild(sCtrlDispRight);

    // actual controls
    // background-color+opacity is necessary for ie, otherwise it pretends the
    // divs have display:none
    sCtrlLeft = new Element('div', {id:'sCtrlLeft'});
    slideshowControls.appendChild(sCtrlLeft);
    sCtrlLeft.setStyle({
        'backgroundColor': 'black',
        'position': 'absolute',
        'left': '0px',
        'top': '0px',
        // 'width': Math.floor(width*.35)+'px',
        'width': '395px',
        'height': height+'px'
    });
    sCtrlLeft.setOpacity(0);
    sCtrlLeft.onmouseover = function() { sCtrlDispLeft.show(); };
    sCtrlLeft.onmouseout = function() { sCtrlDispLeft.hide(); };
    sCtrlLeft.onclick = function() { slideshowGoOffset(-1); };

    sCtrlRight = new Element('div', {id:'sCtrlRight'});
    sCtrlRight.setStyle({
        'backgroundColor': 'black',
        'position': 'absolute',
        // 'left': Math.ceil(width*.65)+'px',
        'left': (width-375)+'px',
        'top': '0px',
        // 'width': Math.floor(width*.35)+'px',
        'width': '375px',
        'height': height+'px'
    });
    sCtrlRight.setOpacity(0);
    sCtrlRight.onmouseover = function() { sCtrlDispRight.show(); };
    sCtrlRight.onmouseout = function() { sCtrlDispRight.hide(); };
    sCtrlRight.onclick = function() { slideshowGoOffset(1); };
    slideshowControls.appendChild(sCtrlRight);

    // options div
    sCtrlOpt = new Element('div', {id:'sCtrlOpt'});
    sCtrlOpt.addClassName('slideshowControl');
    sCtrlOpt.setStyle({
        'position': 'absolute',
        // 'left': Math.ceil(width*.35)+'px',
        'left': '395px',
        'top': '0px',
        'overflow': 'auto',
        // 'width': Math.floor(width*.3)+'px',
        'width': '198px',
        'height': Math.floor(height*.4)+'px'
    });
    sCtrlOpt.setOpacity(0);
    sCtrlOpt.onmouseover = function() { sCtrlOpt.setOpacity(.75); };
    sCtrlOpt.onmouseout = function() { sCtrlOpt.setOpacity(0); };
    slideshowControls.appendChild(sCtrlOpt);

    // image list div
    if(showImageList) {
        sCtrlList = new Element('div', {id:'sCtrlList'});
        sCtrlList.addClassName('slideshowControl');
        sCtrlList.setStyle({
            'position': 'absolute',
            'left': '395px',
            'top': Math.ceil(height*.4)+'px',
            'overflow': 'auto',
            'width': '198px',
            'height': Math.floor(height*.6)+'px'
        });
        sCtrlList.setOpacity(0);
        sCtrlList.onmouseover = function() { sCtrlList.setOpacity(.75); };
        sCtrlList.onmouseout = function() { sCtrlList.setOpacity(0); };
        slideshowControls.appendChild(sCtrlList);
    }

    // init controls
    slideshowControlListInit();
    slideshowControlOptionsInit();
    
    // start slideshow
    $('sCtrlStopGo').update( 'stop' );
    slideshowTimer = setInterval(
        slideshowGoOffset.curry(1), 
        slideshowSpeed*1000
    );
}


function slideshowControlListInit() {
    if(!showImageList) return;
    var s = $('sCtrlList');
    s.update();
    for(var i=0; i<slideshowArray.length; i++) {
        var item = new Element('span', {id: 'sCtrlListItem'+i});
        item.addClassName('slideshowListItem clickable')
        item.update( slideshowArray[i].title );
        item.onclick = slideshowGo.curry(i);
        s.appendChild(item);
        if(i<slideshowArray.length-1) {
            s.appendChild(new Element("br"));
        }
    }
}


function slideshowControlOptionsInit() {
    var s = $('sCtrlOpt');
    s.update();

    var item = new Element('span', {id:'sCtrlCurrent'});
    item.addClassName('slideshowListItem')
    item.update( slideshowArray[slideshowIndex].title );
    s.appendChild(item);
    s.appendChild(new Element('hr'));

    var item = new Element('span');
    item.addClassName('slideshowListItem')
    item.update( "sort:" );
    s.appendChild(item);
    
    var item = new Element('span');
    item.addClassName('slideshowListItem clickable')
    if( slideshowSort == 'name' && slideshowSortDir == 'ascending' )
        item.addClassName('current'); 
    item.update( 'name' );
    item.onclick = function() { slideshowChangeSort('name', 'ascending'); };
    s.appendChild(item);
    s.appendChild(document.createTextNode(" | "));

/*
    var item = new Element('span');
    item.addClassName('slideshowListItem')
    if( slideshowSort == 'name' && slideshowSortDir == 'descending' )
        item.addClassName('current'); 
    item.update( 'name, reverse' );
    item.onclick = function() { slideshowChangeSort('name', 'descending'); };
    s.appendChild(item);
    s.appendChild(document.createTextNode(" | "));
*/

    var item = new Element('span');
    item.addClassName('slideshowListItem clickable')
    if( slideshowSort == 'date' && slideshowSortDir == 'descending' )
        item.addClassName('current'); 
    item.update( 'newest first' );
    item.onclick = function() { slideshowChangeSort('date', 'descending'); };
    s.appendChild(item);
    s.appendChild(document.createTextNode(" | "));

    var item = new Element('span');
    item.addClassName('slideshowListItem clickable')
    if( slideshowSort == 'date' && slideshowSortDir == 'ascending' )
        item.addClassName('current'); 
    item.update( 'oldest first' );
    item.onclick = function() { slideshowChangeSort('date', 'ascending'); };
    s.appendChild(item);
    s.appendChild(document.createTextNode(" | "));
    
    var item = new Element('span');
    item.addClassName('slideshowListItem clickable')
    if( slideshowSort == 'random' ) item.addClassName('current'); 
    item.update( 'random' );
    item.onclick = function() { slideshowChangeSort('random'); };
    s.appendChild(item);
    
    s.appendChild(new Element('hr'));
    
    var stopgo = new Element('span', {id:'sCtrlStopGo'});
    stopgo.addClassName('slideshowListItem clickable')
    stopgo.update( slideshowTimer == null ? 'go' : 'stop' );
    stopgo.onclick = function() { 
        if( slideshowTimer != null ) {
            stopgo.update( 'go' );
            clearInterval(slideshowTimer); 
            slideshowTimer = null;
        } else {
            stopgo.update( 'stop' );
            slideshowTimer = setInterval(
                slideshowGoOffset.curry(1), 
                slideshowSpeed*1000
            );
        }
    };
    s.appendChild(stopgo);

/*
    s.appendChild(document.createTextNode(" | "));
    
    var item = new Element('span');
    item.addClassName('slideshowListItem clickable')
    item.update( 'slower' );
    item.onclick = slideshowChangeSpeed.curry(slideshowSpeed+1);
    s.appendChild(item);
    s.appendChild(document.createTextNode(" | "));
    
    var item = new Element('span');
    item.addClassName('slideshowListItem clickable')
    item.update( 'faster' );
    item.onclick = slideshowChangeSpeed.curry(slideshowSpeed-1);
    s.appendChild(item);
    s.appendChild(document.createTextNode(" ("+slideshowSpeed+"s)"));
    s.appendChild(new Element("br"));
*/
}


/**
    save settings
    apply slideshow sort
    re-initialize control boxes
 */
function slideshowChangeSort(sort, sortDir) {
    slideshowSort = sort;
    if(sortDir) slideshowSortDir = sortDir;
    slideshowSave();
    slideshowApplySort();
    slideshowGo(0);
    slideshowControlOptionsInit();
    slideshowControlListInit();
}


/**
    set new slideshow speed.
    save settings.
    if slideshow is active, reset interval timer
    re-initialize options control box
 */
function slideshowChangeSpeed(speed) {
    slideshowSpeed = speed;
    if( slideshowSpeed < 1 ) slideshowSpeed = 1;
    slideshowSave();
    if( slideshowTimer != null ) {
        clearInterval(slideshowTimer);
        slideshowTimer = setInterval(
            slideshowGoOffset.curry(1), 
            slideshowSpeed*1000
        );
    }
    slideshowControlOptionsInit();
}


/**
    sort slideshowArray according to configured criteria.
    recalculate slideshowIndex to point to the same element as before sorting.
    items with name patterns like "item.jpg", "item_something.jpg",
    "item.somethingelse.jpg" will be grouped together in the output, sorted
    alphabetically in the group.
 */
function slideshowApplySort() {
    var oldItem = slideshowArray[slideshowIndex].name;
    
    // remove all images that are part of a sequence
    var seqItems = [];
    var toSort = [];
    var oA = slideshowArray;
    oA.sort( function(a, b) {
        if( a.name > b.name ) return -1;
        return 1;
    } );
    while( oA.length > 0 ) {
        var item = oA.shift();
        for( var i = 0; i < oA.length; i++ ) {
            if( item.title.startsWith( oA[i].title + "." ) ||
                item.title.startsWith( oA[i].title + "_" ) ) {
                seqItems.push( item );
                item = null;
                break;
            }
        }
        if( item != null ) {
            toSort.push( item );
        }
    }

    // sort the sequence images by title
    seqItems.sort( function(a, b) {
        if( a.name < b.name ) return -1;
        return 1;
    } );

    // apply sorting criteria
    if( slideshowSort == 'name' ) {
        toSort.sort( function(a, b) {
            var ret = 0;
            if( a.name < b.name ) 
                ret = -1;
            else if( a.name > b.name )
                ret = 1;
            return ret * (slideshowSortDir=="ascending" ? -1 : 1);
        } );
    }
    else if( slideshowSort == 'date' ) {
        toSort.sort( function(a, b) {
            var ret = 0;
            if( a.time < b.time ) 
                ret = -1;
            else if( a.time > b.time )
                ret = 1;
            return ret * (slideshowSortDir=="ascending" ? -1 : 1);
        } );
    }
    else if( slideshowSort == 'random' ) {
        var oA = toSort;
        toSort = [];
        while(oA.length > 0) {
            var el = oA.splice( Math.floor(Math.random()*oA.length), 1 );
            toSort.push( el[0] );
        }
    }
    
    // merge sequence items into array
    slideshowArray = [];
    for(var i=0; i<toSort.length; i++) {
        lToSort = toSort[i];
        slideshowArray.push(lToSort);
        for(var j=0; j<seqItems.length; j++) {
            if( seqItems[j].title.startsWith( lToSort.title + "." ) ||
                seqItems[j].title.startsWith( lToSort.title + "_" ) ) {
                slideshowArray.push(seqItems[j]);
            }
        }
    }

    // find new index of currently displayed image
    for(var i=0; i<slideshowArray.length; i++) {
        if( oldItem == slideshowArray[i].name ) {
            slideshowIndex = i;
            break;
        }
    }
}


/**
    display given image.
    save cookie.
    if slideshow is playing, reset interval to prevent skipping.
 */
function slideshowGo(index) {
    if(showImageList) {
        var oldItem = $('sCtrlListItem'+slideshowIndex);
        oldItem.removeClassName('current');
    }
    slideshowIndex = index;
    slideshowSave();
    slideshowImage.src = slideshowArray[slideshowIndex].name;
    slideshowImage.title = slideshowArray[slideshowIndex].title;
    $('sCtrlCurrent').update(slideshowArray[slideshowIndex].title);

    if(showImageList) {
        var newItem = $('sCtrlListItem'+slideshowIndex)
        newItem.addClassName('current');
        $('sCtrlList').scrollTop = newItem.offsetTop;
    }
    if(slideshowTimer != null) {
        clearInterval(slideshowTimer);
        slideshowTimer = setInterval(
            slideshowGoOffset.curry(1), 
            slideshowSpeed*1000
        );
    }
}


function slideshowGoOffset(offset) {
    slideshowGo( (slideshowIndex+offset+slideshowArray.length)
        % slideshowArray.length );
}


function slideshowLoad() {
    var c = document.cookie;
    if( c ) {
        c = c.split("; ");
        for(var i=0; i<c.length; i++) {
            c[i] = c[i].split("=");
            if(c[i][0] == 'sort') {
                slideshowSort = c[i][1];
            }
            else if(c[i][0] == 'sortDir') {
                slideshowSortDir = c[i][1];
            }
            /*
            else if(c[i][0] == 'speed') {
                slideshowSpeed = c[i][1];
            }
            else if(c[i][0] == 'index') {
                slideshowIndex = c[i][1];
                if( isNaN(slideshowIndex) ) slideshowIndex = 0;
                slideshowIndex = (slideshowIndex % slideshowArray.length);
            }
            */
        }
    }
}


function slideshowSave() {
    document.cookie = "sort="+slideshowSort;
    document.cookie = "sortDir="+slideshowSortDir;
    // document.cookie = "speed="+slideshowSpeed;
    // document.cookie = "index="+slideshowIndex;
}



