/*	ImageFlow 0.9
 *
 *	This code is based on Michael L. Perrys Cover flow in Javascript.
 *	For he wrote that "You can take this code and use it as your own" [1]
 *	this is my attempt to improve some things. Feel free to use it! If
 *	you have any questions on it leave me a message in my shoutbox [2].
 *
 *	The reflection is generated server-sided by a slightly hacked  
 *	version of Richard Daveys easyreflections [3] written in PHP.
 *	
 *	The mouse wheel support is an implementation of Adomas Paltanavicius
 *	JavaScript mouse wheel code [4].
 *
 *	Thanks to Stephan Droste ImageFlow is now compatible with Safari 1.x.
 *
 *
 *	[1] http://www.adventuresinsoftware.com/blog/?p=104#comment-1981
 *	[2] http://shoutbox.finnrudolph.de/
 *	[3] http://reflection.corephp.co.uk/v2.php
 *	[4] http://adomas.org/javascript-mouse-wheel/
 */


 
function createImageFlows(theElement) {
    var imageFlowObject;
    for (var i = 0; i < theElement.childNodes.length; i++) {
        createImageFlows(theElement.childNodes[i]);
    }
    //try {
    if (theElement.className == 'imageflow') {
        imageFlowObject = new ImageFlow(theElement);
    }
    //} catch(e) {}
}

function activateImageFlow(theElement) {
    var imageFlowObject;
    try {
        if (document.getElementById(theElement).style.visibility == 'hidden') {
            imageFlowObject = new ImageFlow(document.getElementById(theElement));
        }
    } catch(e) {}
}


function ImageFlow(theElement) {
    /* Configuration variables */
    var conf_reflection_p = 0;         // Sets the height of the reflection in % of the source image 
    var conf_focus = 4;                  // Sets the numbers of images on each side of the focussed one
    var conf_slider_width = 48;          // Sets the px width of the slider div
    var conf_images_cursor = 'pointer';  // Sets the cursor type for all images default is 'default'
    var conf_slider_cursor = 'default';  // Sets the slider cursor type: try "e-resize" default is 'default'
    
    var imageFlowElement = theElement;
    
    
    /* Define global variables */
    var caption_id = 0;
    var new_caption_id = 0;
    var current = 750;
    var target = 0;
    var mem_target = 0;
    var timer = 0;
    var array_images = new Array();
    var new_slider_pos = 0;
    var dragging = false;
    var dragobject = null;
    var dragx = 0;
    var posx = 0;
    var new_posx = 0;
    var xstep = 150;
    
    var images_width = 0;
    var images_top = 0;
    var images_left = 0;
    var max_conf_focus = 0;
    var size = 0;
    var scrollbar_width = 0;
    //var conf_slider_width = 0;
    var max_height = 0;
    var max = 0;
    
    
        
    var imageflow_div = imageFlowElement;
    var img_div = imageFlowElement;
    
        /* Change imageflow div properties */
    imageflow_div.style.textAlign = 'left';
    imageflow_div.style.height = parseInt(imageflow_div.getAttribute('MAX')) + 90 + 'px';
    imageflow_div.style.width = parseInt(imageflow_div.getAttribute('MAX')) * 2.4 + 'px';
    imageflow_div.style.visibility = 'visible';
    //imageflow_div.style.zIndex = ImageFlowZ;
    
    var scrollbar_div = document.createElement("div");
    imageflow_div.appendChild(scrollbar_div);
    scrollbar_div.style.position = 'relative'; 
    scrollbar_div.style.borderBottom = '1px solid #b3b3b3';
    //scrollbar_div.style.zIndex = '1001';
    
    var slider_div = document.createElement("div");
    slider_div.style.position = 'relative';
    //slider_div.style.marginTop = '8px';
    //slider_div.style.marginLeft = '-8px';
    //slider_div.style.zIndex ='1002';
    slider_div.style.width ='48px';
    slider_div.style.height ='16px';
    slider_div.style.border = '2px solid #b3b3b3';
    slider_div.style.background = '#000000';
    scrollbar_div.appendChild(slider_div);
    
    var caption_div = document.createElement("div");
    caption_div.style.fontWeight = 'bold';
    caption_div.style.fontSize = '14px';
    caption_div.style.textAlign = 'center';
    //caption_div.style.zIndex = '1001';
    caption_div.style.position = "relative";
    //caption_div.style.color = '#b3b3b3';
    imageflow_div.appendChild(caption_div);
    
        
    
    
    refresh(true);
    initMouseWheel();
    initMouseDrag();
    glideTo(0, 0);
    
    /* Hide loading bar, show content and initialize mouse event listening after loading */
    //window.onload = function()
    //{
    //}
    
    /* Refresh ImageFlow on window resize */
    function doRefresh(event) {
        refresh();
    }
/*
    window.addEventListener('resize', doRefresh, false);
    window.attachEvent('onresize', doRefresh);
  */  

  try {
      if(imageflow_div.style.position == "absolute" || imageflow_div.parent.style.position == "absolute") {
        if (window.addEventListener) //DOM method for binding an event
            imageflow_div.addEventListener("resize", doRefresh, false)
        else if (window.attachEvent) //IE exclusive method for binding an event
            imageflow_div.attachEvent("onresize", doRefresh)
        else if (document.getElementById) //support older modern browsers
            imageflow_div.onresize=doRefresh
      } else {
        if (window.addEventListener) //DOM method for binding an event
            window.addEventListener("resize", doRefresh, false)
        else if (window.attachEvent) //IE exclusive method for binding an event
            window.attachEvent("onresize", doRefresh)
        else if (document.getElementById) //support older modern browsers
            window.onresize=doRefresh
      }
  } catch (e) {
        if (window.addEventListener) //DOM method for binding an event
            window.addEventListener("resize", doRefresh, false)
        else if (window.attachEvent) //IE exclusive method for binding an event
            window.attachEvent("onresize", doRefresh)
        else if (document.getElementById) //support older modern browsers
            window.onresize=doRefresh
  }
   
    
    /* Fixes the back button issue */
    //window.onunload = function()
    //{
    //  document = null;
    //}
    
    
    function setOpacity(image, value)
    {
        if (image.filters && image.filters[0])
        {
            image.filters[0].opacity = value * 100;
        }
        else
        {
            image.style.opacity = value;
        }
    }
    
    function step()
    {
        switch (target < current-1 || target > current+1) 
        {
            case true:
                moveTo(current + (target-current)/3);
                window.setTimeout(step, 50);
                timer = 1;
                break;
    
            default:
                timer = 0;
                break;
        }
    }
    
    function glideTo(x, new_caption_id)
    {	
        /* Animate gliding to new x position */
        target = x;
        mem_target = x;
        if (timer == 0)
        {
            window.setTimeout(step, 50);
            timer = 1;
        }
        
        /* Display new caption */
        caption_id = new_caption_id;
        caption = img_div.childNodes.item(array_images[caption_id]).getAttribute('alt');
        if (caption == '') caption = '&nbsp;';
        if (img_div.childNodes.item(array_images[caption_id]).getAttribute('goto') != null) {
            caption_div.innerHTML = caption+'<br /><span style="font-weight: normal; font-size: 12px;">Double Click Image to View</span>';
        } else {
            caption_div.innerHTML = caption;
        }
    
        /* Set scrollbar slider to new position */
        if (dragging == false)
        {
            if (max == 1) {
                max = 2;
            }
            new_slider_pos = (scrollbar_width * (-(x*100/((max-1)*xstep))) / 100) - new_posx;
            slider_div.style.marginLeft = (new_slider_pos - conf_slider_width) + 'px';
        }
    }
    
    function moveTo(x)
    {
        current = x;
        var zIndex = max + 2000;
        //alert(images_left);
        
        /* Main loop */
        for (var index = 0; index < max; index++)
        {
            var image = img_div.childNodes.item(array_images[index]);
            var current_image = index * -xstep;
            
            
    
            /* Don't display images that are not conf_focussed */
            if ((x < -(xstep*5.5)) || (x > (xstep*5.5)))
            {
                image.style.visibility = 'hidden';
                image.style.display = 'none';
            }
            else 
            {
                //alert(index);
                var z = Math.sqrt(10000 + x * x) + 100;
                var xs = x / z * size + size;
    
                /* Still hide images until they are processed, but set display style to block */
                image.style.display = 'block';
            
                /* Process new image height and image width */
                var new_img_h = (image.h  ) / (z / 100) * 2 ;// * size;
                var new_img_w = (image.w ) / (z / 100) * 2;
                //var new_img_top = ((parseInt(imageflow_div.style.height) - new_img_h) * 0.5) - 25 + images_top;
                var new_img_top = ((parseInt(imageflow_div.style.height) - new_img_h) * 0.5) - 25;// + images_top;
                //var new_img_top = 0;
                var new_img_left = (xs - (image.pc / 2) / z  - (new_img_w / 2));
                if (imageflow_div.style.position != 'absolute') {
                    new_img_top += images_top;
                    new_img_left += images_left;
                }
                //alert(image.src + ": " + new_img_top + ' -- ' + new_img_left);
                /* Set new image properties */
                image.style.left = new_img_left + 'px'; // +12 is just a guess
                if(new_img_w && new_img_h)
                { 
                    image.style.height = new_img_h + 'px'; 
                    image.style.width = new_img_w + 'px'; 
                    image.style.top = new_img_top + 'px';
                }
                
                /* Set the image opacity */
                if ((x < -(xstep*4.5)) || (x > (xstep*4.5)))
                {
                    if (x > 0)
                        setOpacity(image, ((xstep*5.5-x)/xstep) * .1);
                    else
                        setOpacity(image, ((xstep*5.5+x)/xstep) * .1);
                }
                else
                {
                    setOpacity(image, 1);
                }
    
                image.style.visibility = 'visible';
    
                /* Set image layer through zIndex */
                switch ( x < 0 )
                {
                    case true:
                        zIndex++;
                        break;
    
                    default:
                        zIndex = zIndex - 1;
                        break;
                }
                
                /* Change zIndex and onclick function of the focussed image */
                switch ( image.i == caption_id )
                {
                    case false:
                        image.onclick = function() { glideTo(this.x_pos, this.i); }
                        break;
    
                    default:
                        zIndex = zIndex + 1;
                        image.onclick = function() { /*document.location = this.url;*/ }
                        break;
                }
                image.style.zIndex = zIndex;
            }
            x += xstep;
        }
    }
    
    /* Main function */
    function refresh(onload)
    {
        
        
        images_width = imageflow_div.offsetWidth;
        
        /* Cache global variables, that only change on refresh */
        images_top = getTop(imageflow_div);
        images_left = getLeft(imageflow_div);
        //alert("hello");
        
        
        max_conf_focus = conf_focus * xstep;
        size = images_width * 0.5;
        scrollbar_width = images_width * 0.6;
        conf_slider_width = conf_slider_width * 0.5;
        max_height = images_width * 0.51;
        
        /* Change scrollbar div properties */
        scrollbar_div.style.marginTop = images_width * 0.02 + 'px';
        scrollbar_div.style.marginLeft = images_width * 0.2 + 'px';
        scrollbar_div.style.width = scrollbar_width + 'px';
        scrollbar_div.style.top = parseInt(imageflow_div.style.height) - 45 + 'px';
       
        /* Set slider attributes */
        slider_div.onmousedown = function () { dragstart(this); };
        //slider_div.onmouseout = function () { dragstop(); };
        slider_div.style.cursor = conf_slider_cursor;
        slider_div.style.top = parseInt(slider_div.offsetHeight) / 2 + 'px';
    
        /* Change captions div properties */
        caption_div.style.width = images_width + 'px';
        caption_div.style.top = parseInt(scrollbar_div.style.top) - 43 - (parseInt(caption_div.offsetHeight) ) + 'px';

        /* Cache EVERYTHING! */
        max = img_div.childNodes.length;
        //alert(max);
        var i = 0;
        for (var index = 0; index < max; index++)
        { 
            var image = img_div.childNodes.item(index);
            if (image.nodeType == 1 && image.nodeName == "IMG")
            {
                array_images[i] = index;
                
                /* Set image onclick by adding i and x_pos as attributes! */
                image.onclick = function() { glideTo(this.x_pos, this.i); }
                image.x_pos = (-i * xstep);
                image.i = i;
                
                /* Add width and height as attributes ONLY once onload */
                if(onload == true)
                {
                    //if (trim(image.getAttribute('holdsrc')) != "") {
                        image.src = image.getAttribute('holdsrc');
                    //}
                    image.w = image.getAttribute('w');
                    image.h = image.getAttribute('h');
                    image.style.position = 'absolute';
                    image.style.top = '0px';
                    image.style.border = 'none';
                    image.style.visibility = 'hidden';
                    image.style.display = 'none';
                    image.style.filter = 'alpha(opacity=100)';
                    image.style.opacity = '1';
                    image.style.zIndex = '1000';
               }
        
                /* Check source image format. Get image height minus reflection height! */
                /*
                switch ((image.w + 1) > (image.h / (conf_reflection_p + 1))) 
                {
                    // Landscape format 
                    case true:
                        image.pc = 118;
                        break;
    
                    // Portrait and square format 
                    default:
                        image.pc = 100;
                        break;
                }
                */
                if (image.w > image.h) {
                    image.pc = image.w / image.h * 100;
                } else {
                    image.pc = image.h / image.w * 100;
                }
                
                /* Set ondblclick event */
                image.url = image.getAttribute('goto');
                if (image.url != null) {
                    image.ondblclick = function() { document.location = this.url; }
                }
    
                /* Set image cursor type */
                image.style.cursor = conf_images_cursor;
    
                i++;
            }
        }
        max = array_images.length;
    
        /* Display images in current order */
        moveTo(current);
        glideTo(current, caption_id);
    }
    
    /* Show/hide element functions */
    function show(id)
    {
        var element = document.getElementById(id);
        element.style.visibility = 'visible';
    }
    function hide(id)
    {
        var element = document.getElementById(id);
        element.style.visibility = 'hidden';
        element.style.display = 'none';
    }
    

    
    /* Handle the wheel angle change (delta) of the mouse wheel */
    function handle(delta)
    {
        var change = false;
        switch (delta > 0)
        {
            case true:
                if(caption_id >= 1)
                {
                    target = target + xstep;
                    new_caption_id = caption_id - 1;
                    change = true;
                }
                break;
    
            default:
                if(caption_id < (max-1))
                {
                    target = target - xstep;
                    new_caption_id = caption_id + 1;
                    change = true;
                }
                break;
        }
    
        /* Glide to next (mouse wheel down) / previous (mouse wheel up) image */
        if (change == true)
        {
            glideTo(target, new_caption_id);
        }
    }
    
    /* Event handler for mouse wheel event */
    function wheel(event)
    {
        var delta = 0;
        if (!event) event = window.event;
        if (event.wheelDelta)
        {
            delta = event.wheelDelta / 120;
        }
        else if (event.detail)
        {
            delta = -event.detail / 3;
        }
        if (delta) handle(delta);
        if (event.preventDefault) event.preventDefault();
        event.returnValue = false;
    }
    
    /* Initialize mouse wheel event listener */
    function initMouseWheel()
    {
        if(window.addEventListener) imageflow_div.addEventListener('DOMMouseScroll', wheel, false);
        imageflow_div.onmousewheel = wheel;
    }
    
    /* This function is called to drag an object (= slider div) */
    function dragstart(element)
    {
        dragobject = element;
        dragx = posx - dragobject.offsetLeft + new_slider_pos;
    }
    
    /* This function is called to stop dragging an object */
    function dragstop()
    {
        dragobject = null;
        dragging = false;
    }
    
    /* This function is called on mouse movement and moves an object (= slider div) on user action */
    function drag(e)
    {
        posx = document.all ? window.event.clientX : e.pageX;
        if(dragobject != null)
        {
            dragging = true;
            new_posx = (posx - dragx) + conf_slider_width;
    
            /* Make sure, that the slider is moved in proper relation to previous movements by the glideTo function */
            if(new_posx < ( - new_slider_pos)) new_posx = - new_slider_pos;
            if(new_posx > (scrollbar_width - new_slider_pos)) new_posx = scrollbar_width - new_slider_pos;
            
            var slider_pos = (new_posx + new_slider_pos);
            var step_width = slider_pos / ((scrollbar_width) / (max-1));
            var image_number = Math.round(step_width);
            var new_target = (image_number) * -xstep;
            var new_caption_id = image_number;
    
            dragobject.style.left = new_posx + 'px';
            glideTo(new_target, new_caption_id);
        }
    }
    
    /* Initialize mouse event listener */
    function initMouseDrag()
    {
        imageflow_div.onmousemove = drag;
        imageflow_div.onmouseup = dragstop;
    
        /* Avoid text and image selection while dragging  */
        document.onselectstart = function () 
        {
            if (dragging == true)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
    }
    
    function getTop( oElement )
    {
        var iReturnValue = 0;
        while( oElement != null ) {
            iReturnValue += oElement.offsetTop;
            oElement = oElement.offsetParent;
        }
        return iReturnValue;
    }    
    function getLeft( oElement )
    {
        var iReturnValue = 0;
        while( oElement != null ) {
            iReturnValue += oElement.offsetLeft;
            oElement = oElement.offsetParent;
        }
        return iReturnValue;
    }    
}

