
window.onload = init;
var d=document;
var zInterval=null;
var imageCoordinates = new Array();         // array to hold the x,y of each image
var imageObjects = new Array();         // object reference array to the images
var imageDimensions = new Array();      // array to hold the current width and height of the images
var imageStart = new Array();       // the original x/y positions of each image
var imageCourse = new Array();      // the x/y coordinates the image must travel to get from point A to point B
var currentOpacity = new Array();       // current transparency of the image
var activeImage= 10;             // index of the currently active image
var prevImage= 10;           // index of the formerly active image
var animationIndex = new Array();       // keeps track of where we need to be in the imageCourse array for each animation loop
var movementSteps = new Array();        // the width and height increments required for each image to resize by while moving
var useOpacity=1;               // boolean to denote use of opacity filters
var iSpeed=15;               // the rate at which we step through the imageCourse array
var isAnimated=0;               // stops additional threads from running if one already is.
var TOTAL_IMAGES=12;            // the total number of images
var IMAGES_PER_ROW=3;           // how many images per row
var IMAGE_MIN_SIZE=70;          // the minimum size of the thumbnails
var IMAGE_MAX_WIDTH=140;        // max width of the enlarged images
var IMAGE_MAX_HEIGHT=140;       // max height of the enlarged images
var IMAGE_SPACING=135;  
var IMAGE_SPACING_TOP=12;// spacing between the thumbnails
var DEST_Y=-78;             // the y position of where the animation stops
var DEST_X=709;             // the x position of where the animation stops
var DEFAULT_CAPTION=" "

function init() {
    if(!document.getElementById)return; // bail out if this is an old browser
    initThumbnails();           // initialize the thumbnail images
    initCourse();           // initialize the x/y courses the images will need to travel
    initSteps();            // intialize the step increments for the width and height changes
}

function initThumbnails() {
    x=0; y=0; i=0; z=0;
    // set the default caption up
    d.getElementById("caption").innerHTML = DEFAULT_CAPTION;
    // loop over how many images we have to deal with
    while(i<TOTAL_IMAGES) {
        // create an object reference variable to the image
        if(!imageObjects[i])imageObjects[i]=d.getElementById("image"+i);

        // set the top and left of the image
        imageObjects[i].style.left = x + "px";
        imageObjects[i].style.top = y + "px";

        // set up the bogus "xid" attribute to ID the images when they are clicked on
        imageObjects[i].xid=i;

        // set up the onclick event
        imageObjects[i].onclick=function(){animate(this.xid)}

        // set up the imageStart array for this image
        if(!imageStart[i])imageStart[i]=new Array(x,y);

        // increment the x coordinate for the next image
        x+=IMAGE_MIN_SIZE+IMAGE_SPACING;

        // set up the coordinates for this image
        imageCoordinates[i]=new Array(x,y);

        // and its initial width
        imageDimensions[i] = new Array(70,70);

        // and it initial opacity. MSIE takes 0-100 values for opacity. All others take floating points.
        currentOpacity[i]=document.all?50:.5;
    
        // set the animationIndex for this image to 0
        animationIndex[i]=0;

        // if we've got as many images in the row as we want, start the next row
        z++;
        if(z>=IMAGES_PER_ROW) {
            x=0; z=0;
            y+=IMAGE_MIN_SIZE+IMAGE_SPACING_TOP;
        }
        i++;
    }
}

function initCourse() {
    // initialize the imageCourse array for each image
    for(i=0;i<imageStart.length;i++)imageCourse[i] = plotCourse(DEST_X,DEST_Y,imageStart[i][0],imageStart[i][1]);
}

function initSteps() {
    // initialize the step increments for the width and height changes.
    for(i=0;i<imageCourse.length;i++) {
        wStep = Math.round(imageCourse[i].length/iSpeed);
        wStep = Math.round(140/wStep);
        hStep = Math.round(imageCourse[i].length/iSpeed);
        hStep = Math.round(140/hStep);
    
        movementSteps[i]=new Array(wStep,hStep);
    }
}

function animate(index) {
    // exit out of the function if there is already an animation thread running
    if(zInterval)return;

    // no current active image. that means either a single image is returning (no overlap) or we're running for the first time
    // make prevImage -1 so we dont run any animation loops we dont need to.
    if(activeImage==-1)prevImage=-1;
    if(index==activeImage) {
        // the user has clicked on the enlarged image. set prevImage to activeImage and set activeImage to -1
        prevImage=activeImage;
        imageObjects[activeImage].style.zIndex=0;
        activeImage=-1; 
    } else {
        // set up the previous image so we know which to send back and where to send it.
        if(activeImage>-1)prevImage=activeImage;
        activeImage=index;
        imageObjects[activeImage].style.zIndex=0;
        if(prevImage>-1)imageObjects[prevImage].style.zIndex=1;
    }

    // begin the animation thread
    zInterval = setInterval("slideImage()",10);
}

function setImagePosition(index) {
    // set the positions and width of the images. These can fall out of range, hence the try/catch statement
    try {
        imageObjects[index].style.top = imageCourse[index][animationIndex[index]][1]+"px";
        imageObjects[index].style.left = imageCourse[index][animationIndex[index]][0]+"px";
        imageObjects[index].style.width=imageDimensions[index][0]+"px";
        imageObjects[index].style.height=imageDimensions[index][1]+"px";
    } catch(err) { }
}

function setImageOpacity(index) {
    // set the opacity of the object. Once for Gecko, once for Safari and once for MSIE.
    if(!useOpacity)return;
    imageObjects[index].style.filter="alpha(opacity=" + currentOpacity[activeImage] + ")";
    imageObjects[index].style.MozOpacity=currentOpacity[activeImage];
    imageObjects[index].style.opacity=currentOpacity[activeImage];
}

function slideImage() {
    // if we have an active image, meaning the one that is being enlarged...
    if(activeImage>-1) {
        // set up its width,height,top and left
        setImagePosition(activeImage);
        // set up its opacity
        currentOpacity[activeImage]+=d.all?5:.05;
        setImageOpacity(activeImage);
        // if its width is less than 140, increase it. likewise with its height
        if(imageDimensions[activeImage][0]<140)imageDimensions[activeImage][0]+= movementSteps[activeImage][0];
        if(imageDimensions[activeImage][1]<140)imageDimensions[activeImage][1]+= movementSteps[activeImage][1];
        // increment our current index for imageCourse by value of iSpeed
        animationIndex[activeImage]+=iSpeed;
    }

    // do the same as above for images returning to thumbnail size, only decrementing values this time
    if(prevImage>-1) {
        setImagePosition(prevImage);
        currentOpacity[prevImage]-=d.all?5:.05;
        setImageOpacity(prevImage);
        if(imageDimensions[prevImage][0]>70)imageDimensions[prevImage][0]-=movementSteps[prevImage][0];
        if(imageDimensions[prevImage][1]>70)imageDimensions[prevImage][1]-=movementSteps[prevImage][1];
        animationIndex[prevImage]-=iSpeed;
    }

    // has our animation finished?
    if(isFinished()) {
        // if activeImage is -1, we have no enlarged image. reset the animation index and put the default caption back in.
        if(activeImage==-1) {
            d.getElementById("caption").innerHTML = DEFAULT_CAPTION;
            animationIndex[prevImage]=0;
        }
        // we've got an active image.
        if(activeImage>-1) {
            // set the animation index to the length of imageCourse so we can start at the end of that array 
            // for when this image becomes a thumbnail again
            animationIndex[activeImage] = imageCourse[activeImage].length;
            // set the final top,left,width and height of the image, just in case they're off
            imageObjects[activeImage].style.top=DEST_Y+"px";
            imageObjects[activeImage].style.left=DEST_X+"px";
            imageObjects[activeImage].style.width="140px";
            imageObjects[activeImage].style.height="140px";
            // set up the final opacity of the image if useOpacity is true
            if(useOpacity) {
                imageObjects[activeImage].style.MozOpacity=.99;
                imageObjects[activeImage].style.filter="alpha(opacity=100)";
                imageObjects[activeImage].style.opacity=1.0;
            }
     
        } 
        // do the same for the thumbnail image.
        if(prevImage>-1) {
            animationIndex[prevImage]=0;
            imageObjects[prevImage].style.top = imageStart[prevImage][1]+"px";
            imageObjects[prevImage].style.left = imageStart[prevImage][0]+"px";
            imageObjects[prevImage].style.width="70px";
            imageObjects[prevImage].style.height="70px";
        }
        // stop the animation thread
        clearInterval(zInterval);
        zInterval=null;
    }
}

// checks to see if the thumbnail and enlarged image are at their final positions
// by checking the animationIndex value against the length of the images imageCourse array.
function isFinished() {
    if(activeImage>-1 && prevImage>-1)if(animationIndex[activeImage]>=imageCourse[activeImage].length && animationIndex[prevImage]<=0) return true;
    if(activeImage>-1 && prevImage==-1) if(animationIndex[activeImage]>=imageCourse[activeImage].length)return true;
    if(activeImage==-1 && prevImage>-1) if(animationIndex[prevImage]<=0)return true;
    return false;
}

// this function simply resets the opacity of the objects when the check box is clicked.
function disableOpacity(bool) {
    if(bool) {
        useOpacity=0;
        for(i=0;i<imageObjects.length;i++) {
            imageObjects[i].style.MozOpacity=1.0;
            imageObjects[i].style.opacity=1.0;
            imageObjects[i].style.filter="alpha(opacity=100)";
        }
    } else {
        location.reload();
    }
}

// this function calculates the required coordinates to go from point A to point B and returns them as an array.
// originally written by Dean Taylor for Web Paint's line functions (slayeroffice.com/tools/web_paint)
// also used in Missile Command (slayeroffice.com/arcade/missile_command)
function plotCourse(fX,fY,oX,oY) {

    dx = Math.abs(fX-oX);
    dy = Math.abs(fY-oY);
    max = dx > dy ? dx : dy;
    x_inc = dx / max;
    y_inc = dy / max;

    Xp = oX
    Yp = oY;

    path = new Array();
    pathCount = 0;

    if(fX>oX && fY > oY) {
        if(oX<fX && oY<fY) {
            while (Xp < fX) {
                nextX = Math.round(Xp);
                nextY = Math.round(Yp);
                path[pathCount] = new Array(nextX,nextY);
                pathCount++;
                Xp += x_inc;
                Yp += y_inc;
            }
        } else {
            while (Xp > fX) {
                nextX = Math.round(Xp);
                nextY = Math.round(Yp);
                path[pathCount] = new Array(nextX,nextY);
                pathCount++;
                Xp -= x_inc;
                Yp += y_inc;
            }       
        }   
    } else {
        if(oX<fX && oY>fY) {
            while (Xp < fX) {
                nextX = Math.round(Xp);
                nextY = Math.round(Yp);
                path[pathCount] = new Array(nextX,nextY);
                pathCount++;
                Xp += x_inc;
                Yp -= y_inc;
            }
        } else {
            while (Xp > fX) {
                nextX = Math.round(Xp);
                nextY = Math.round(Yp);
                path[pathCount] = new Array(nextX,nextY);
                pathCount++;
                Xp -= x_inc;
                Yp -= y_inc;
            }
        }
    }
    return path;
}
