﻿// JScript File

// Softimax SlideShow - Copyright 2009
//
/*

Usage:
    
    SS_CreateSlideShow("http://.../config.xml", "containerName");
        Note: if xml contains "slideshowOn = true" config, the slideshow automatically starts

    SS_StartSlideShow("containerName");
    SS_StartSlideShowDelayed("containerName", mSec);
    SS_PauseSlideShow("containerName");
    SS_StopSlideShow("containerName");
        Note: start, pause and stop the slideshow. If you call SS_PauseSlideShow, then 
        SS_StartSlideShow continues slideshow frome the last point. SS_StopSlideShow
        otherwise reset all info, so next SS_StartSlideShow call starts from zero.
        A previous call to SS_CreateSlideShow is needed
        
    SS_IsRunning("containerName")
        Note: return true is slide show is running
        
        
Library for external use:
    
    SS_SLIDESHOW_DEFINED
        Note: if this value = 1 then this Javascript is loaded
        
    SS_GetKenBurns_Left(containerWidth, imageWidth, kenBurnsCode)
    SS_GetKenBurns_Top(containerHeight, imageHeight, kenBurnsCode)
        Note: kenBurnsCode examples: LT (for LeftTop), TL (the same..), LM, BR, ...
        where chars code is: Left, Center, Right, Top, Middle, Bottom
        (Center is horizontally, Middle is vertically) 

*/


var SS_SLIDESHOW_DEFINED = 1;
var SS_ListOfSlideShow = new Array();
var SS_ImageLoaderInterval = 100;
var SS_EngineInterval = 50;
var SS_DefaultZIndex = 100;

function SS_IsRunning(containerName)
{
    var info = SS_ListOfSlideShow[containerName];
    return (info["hEngine"] != 0);
}
function SS_StartSlideShowDelayed(containerName, time)
{
    var info = SS_ListOfSlideShow[containerName];
    if (time > 2000)
        info["longTimeout"] = 1;
    else
        info["longTimeout"] = 0;
    info["hEngine"] = window.setTimeout("SS_EngineCycle('" + containerName + "')", time);
}
function SS_StartSlideShow(containerName)
{
    var info = SS_ListOfSlideShow[containerName];
    info["longTimeout"] = 0;
    info["hEngine"] = window.setTimeout("SS_EngineCycle('" + containerName + "')", SS_EngineInterval);
}
function SS_StopSlideShow(containerName)
{
    var info = SS_ListOfSlideShow[containerName];    
    info["action"] = "stop";
    
    // Break long time response
    if (info["longTimeout"] == 1)
    {
        window.clearTimeout(info["hEngine"]);
        info["hEngine"] = window.setTimeout("SS_EngineCycle('" + containerName + "')", SS_EngineInterval);
    }    
    //window.clearTimeout(info["hEngine"]);
    //info["hEngine"] = 0;
    //info["currImage"] = -1;
    //info["prevImage"] = -1;
}
function SS_PauseSlideShow(containerName)
{
    var info = SS_ListOfSlideShow[containerName];    
    info["action"] = "pause";
    
    // Break long time response
    if (info["longTimeout"] == 1)
    {
        window.clearTimeout(info["hEngine"]);
        info["hEngine"] = window.setTimeout("SS_EngineCycle('" + containerName + "')", SS_EngineInterval);
    }    
    //info["hEngine"] = 0;
}

function SS_GetXMLDoc(url)
{
    var xmlhttp=null;
    if (window.XMLHttpRequest)
    {   xmlhttp = new XMLHttpRequest();   }
    else if (window.ActiveXObject)
    {   
        try
        {   xmlhttp = new ActiveXObject("MSXML2.XMLHTTP");  }
        catch (e)
        {   xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");  }
    }
    xmlhttp.open("GET", url, false);
    xmlhttp.send("");
    
    var xmlDoc;
    if (xmlhttp!=null)
    {
        try //Internet Explorer
        {
            xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.async="false";
            xmlDoc.loadXML(xmlhttp.responseText);
            return xmlDoc;
        }
        catch(e)
        {
            parser=new DOMParser();
            xmlDoc=parser.parseFromString(xmlhttp.responseText,"text/xml");
            return xmlDoc;
        }
    }
    return null;

}

function SS_GetChildElements(node) 
{
    var elements = new Array();
    for (var i=0; i < node.childNodes.length;  i++)  
    {
        if(node.childNodes[i].nodeType == 1) 
        {
            elements.push(node.childNodes[i]);
        }
    }
    return elements;
}
function SS_IsImageDownloaded(img) 
{
    if (!img.complete) 
    {
        return false;
    }
    if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) 
    {
        return false;
    }
    return true;
}
function SS_GetKenBurns_Left(containerWidth, imageWidth, kenBurnsCode)
{
    switch (kenBurnsCode)
    {
        case "LT":
        case "TL":
        case "LM":
        case "ML":
        case "LB":
        case "BL":
            return 0;
            break;    
            
        case "CT":
        case "TC":
        case "CM":
        case "MC":
        case "CB":
        case "BC":
            return (containerWidth - imageWidth) / 2.0;
            break;
                        
        case "RT":
        case "TR":
        case "RM":
        case "MR":
        case "RB":
        case "BR":
            return containerWidth - imageWidth;
            break;
    }
}
function SS_GetKenBurns_Top(containerHeight, imageHeight, kenBurnsCode)
{
    switch (kenBurnsCode)
    {
        case "LT":
        case "TL":
        case "CT":
        case "TC":
        case "RT":
        case "TR":
            return 0;
            break;    
            
        case "LM":
        case "ML":
        case "CM":
        case "MC":
        case "RM":
        case "MR":
            return (containerHeight - imageHeight) / 2.0;
            break;
                        
        case "LB":
        case "BL":
        case "CB":
        case "BC":
        case "RB":
        case "BR":
            return containerHeight - imageHeight;
            break;
    }
}
function SS_CreateSlideShow_LoadImages(containerName)
{
    if (MO_MOVING_OBJECT_DEFINED!=1)
    {
        alert("Softimax MovingObject library is needed");
        return;
    }

    var info = SS_ListOfSlideShow[containerName];
    var images = info["images"];
    var imageIndex = info["imagesloaded"];    
    var infoImage = images[imageIndex];
   
        
    var objImg = document.getElementById(infoImage["id"]);
    
    if (SS_IsImageDownloaded(objImg))
    {
        //window.status += "L";
        var imgW = 0;
        var imgH = 0;
        
        if (typeof objImg.naturalWidth != "undefined")
        {
            imgW = objImg.naturalWidth;
            imgH = objImg.naturalHeight;
        }
        else
        {
            var tempImage = new Image();
            tempImage.src = objImg.src
            imgW = tempImage.width;
            imgH = tempImage.height;
        }
        
        infoImage["ok"] = 1;
        if (infoImage["kenBurns"]==null)
        {
            var startLeft = SS_GetKenBurns_Left(info["width"], imgW, "MC");
            var startTop = SS_GetKenBurns_Top(info["height"], imgH, "MC");
            objImg.style.left = startLeft + "px";
            objImg.style.top = startTop + "px";                       
        }
        else
        {
            var kenBurns = infoImage["kenBurns"];
            var kenBurnsParts = kenBurns.split(";");
            if (kenBurnsParts.length == 4)
            {
                var totalTime = infoImage["transition"] + infoImage["time"]
                var totalSteps = totalTime / SS_EngineInterval;
                
                infoImage["totalSteps"] = totalSteps;
                infoImage["step"] = 0;
                
                var startWidth = imgW * (parseInt(kenBurnsParts[0]) / 100.0);
                var startHeight = imgH * (parseInt(kenBurnsParts[0]) / 100.0);
                var endWidth = imgW * (parseInt(kenBurnsParts[1]) / 100.0);
                var endHeight = imgH * (parseInt(kenBurnsParts[1]) / 100.0);
                infoImage["startWidth"] = startWidth;
                infoImage["startHeight"] = startHeight;
                infoImage["dW"] = (endWidth - startWidth) / totalSteps;
                infoImage["dH"] = (endHeight - startHeight) / totalSteps;
                infoImage["width"] = startWidth;
                infoImage["height"] = startHeight;
                
                var startLeft = SS_GetKenBurns_Left(info["width"], startWidth, kenBurnsParts[2]);
                var startTop = SS_GetKenBurns_Top(info["height"], startHeight, kenBurnsParts[2]);
                var endLeft = SS_GetKenBurns_Left(info["width"], endWidth, kenBurnsParts[3]);
                var endTop = SS_GetKenBurns_Top(info["height"], endHeight, kenBurnsParts[3]);
                infoImage["startLeft"] = startLeft;
                infoImage["startTop"] = startTop;
                infoImage["dL"] = (endLeft - startLeft) / totalSteps;
                infoImage["dT"] = (endTop - startTop) / totalSteps;
                infoImage["left"] = startLeft;
                infoImage["top"] = startTop;
                
                objImg.style.left = startLeft + "px";
                objImg.style.top = startTop + "px"; 
                objImg.style.width = startWidth + "px";
                objImg.style.height = startHeight + "px"; 
            }
        }

        // <--Transition 1--><------------------Time 1---------------------> - - - - - - - - > 
        //                                                                  <--Transition 2--><------------------Time 2--------------------->
        infoImage["opacity"] = 0.0;
        if (infoImage["transition"] == 0)             
            infoImage["dAlpha"] = 100;
        else
            infoImage["dAlpha"] = 100.0 / (infoImage["transition"] / SS_EngineInterval);
        
        
        // Load next image
        imageIndex = imageIndex + 1;
        info["imagesloaded"] = imageIndex;
        if (imageIndex < info["imagescount"])
        {
            infoImage = images[imageIndex];
            objImg = document.getElementById(infoImage["id"]);
            objImg.src = infoImage["src"];        
        
            SS_ListOfSlideShow[containerName]["hLoader"] = window.setTimeout("SS_CreateSlideShow_LoadImages('" + containerName + "')", SS_ImageLoaderInterval);
        }
    }
    else
    {
        SS_ListOfSlideShow[containerName]["hLoader"] = window.setTimeout("SS_CreateSlideShow_LoadImages('" + containerName + "')", SS_ImageLoaderInterval);
    }
}
function SS_CreateSlideShow(xmlConfigUrl, containerName)
{
    var xmlDoc = SS_GetXMLDoc(xmlConfigUrl);
    if (xmlDoc == null) return;
    var xmlRoot = xmlDoc.documentElement;
    
    var objContainer = document.getElementById(containerName);
    var objContainerStyle = objContainer.style;

    var slideShow_Width = xmlRoot.getAttribute('width');
    var slideShow_Height = xmlRoot.getAttribute('height');
    var slideShow_PreloaderHTMLColor = xmlRoot.getAttribute('preloaderHTMLColor');

    if (slideShow_Width!=null) objContainerStyle.width = slideShow_Width + "px";
    if (slideShow_Height!=null) objContainerStyle.height = slideShow_Height + "px";
    if (slideShow_PreloaderHTMLColor!=null) objContainerStyle.backgroundColor = slideShow_PreloaderHTMLColor;
    objContainerStyle.overflow = "hidden";
    
    var infoImages = new Array();
    var xmlImages = SS_GetChildElements(xmlRoot);
    for (var i=0; i < xmlImages.length;  i++)  
    {
        var xmlImage = xmlImages[i];
        var image_Src = xmlImage.getAttribute('src');
        
        var objImg = document.createElement('img');
        if (i==0) objImg.src = image_Src;
        objImg.setAttribute('id', containerName + "" + i);
        objImg.style.position = "absolute";
        objImg.style.left = "0px";
        objImg.style.top = "0px";
        objImg.style.display = "none";
        objImg.style.zIndex = SS_DefaultZIndex;
        objContainer.appendChild(objImg);
        
        var infoImage = new Array();
        infoImage["id"] = containerName + "" + i;
        infoImage["ok"] = 0;
        infoImage["src"] = image_Src;      
        infoImage["transition"] = parseInt( xmlImage.getAttribute('transition') ) * 1000;
        infoImage["time"] = parseInt( xmlImage.getAttribute('time') ) * 1000;
        infoImage["kenBurns"] = xmlImage.getAttribute('kenBurns');
        infoImages[i] = infoImage;
    }
    
    var info = new Array();
    info["width"] = parseInt(slideShow_Width);
    info["height"] = parseInt(slideShow_Height);
    info["images"] = infoImages;
    info["imagescount"] = xmlImages.length;
    info["imagesloaded"] = 0;
    info["currImage"] = -1;
    info["prevImage"] = -1;
    info["hLoader"] = window.setTimeout("SS_CreateSlideShow_LoadImages('" + containerName + "')", SS_ImageLoaderInterval);
    SS_ListOfSlideShow[containerName] = info;
    
    if (xmlRoot.getAttribute('slideshowOn') == "true")
    {
        info["longTimeout"] = 0;
        info["hEngine"] = window.setTimeout("SS_EngineCycle('" + containerName + "')", SS_EngineInterval);
    }
}
function SS_EngineCycle(containerName)
{
    var info = SS_ListOfSlideShow[containerName];    
    var currImage = info["currImage"];
    var imagesLoaded = info["imagesloaded"];
    
    if (currImage==-1) currImage++;
    if (currImage < imagesLoaded)
    {
        var infoImage = info["images"][currImage];
        if (infoImage["ok"] == 1)
        {
            info["currImage"] = currImage;
            
            var nextImage = false;
            var objImage = document.getElementById(infoImage["id"]);
            var objPrevImage = null;
            if (info["prevImage"]!=-1) 
                objPrevImage = document.getElementById(info["images"][info["prevImage"]]["id"]);

            var opacityChanged = false;
            if (infoImage["opacity"] < 100)
            {
                if (objPrevImage!=null) objPrevImage.style.zIndex = SS_DefaultZIndex;
                opacityChanged = true;
                
                infoImage["opacity"] += infoImage["dAlpha"];
                if (infoImage["opacity"]>=100) infoImage["opacity"] = 100;
                objImage.style.display = "block";
                objImage.style.zIndex = SS_DefaultZIndex + 1;
                MO_ChangeOpacity(objImage.style,infoImage["opacity"]);
            }
            if (infoImage["opacity"]==100)
            {
                if (objPrevImage!=null) objPrevImage.style.display = "none";
                
                // The right place for stopping slideshow
                if (info["action"]=="pause")
                {
                    info["action"] = "";
                    info["hEngine"] = 0;
                    return;
                }
                else if (info["action"]=="stop")
                {
                    info["action"] = "";
                    info["hEngine"] = 0;
                    info["currImage"] = -1;
                    info["prevImage"] = -1;
                    return;
                }
            }       
                    
            if (infoImage["kenBurns"]==null)
            {
                if (infoImage["opacity"] < 100)
                {       
                    // Fading
                    //window.status += "f";
                    info["longTimeout"] = 0;
                    info["hEngine"] = window.setTimeout("SS_EngineCycle('" + containerName + "')", SS_EngineInterval);
                }             
                else if (opacityChanged)
                {
                    // Simple showing
                    //window.status += "T";
                    info["longTimeout"] = 1;
                    info["hEngine"] = window.setTimeout("SS_EngineCycle('" + containerName + "')", infoImage["time"]);
                }
                else
                    nextImage = true;
            }
            else
            {
                if (infoImage["step"]==0)
                {
                    infoImage["left"] = infoImage["startLeft"];
                    infoImage["width"] = infoImage["startWidth"];
                    infoImage["top"] = infoImage["startTop"];
                    infoImage["height"] = infoImage["startHeight"];
                }
                else
                {
                    infoImage["left"] += infoImage["dL"];
                    infoImage["width"] += infoImage["dW"];
                    infoImage["top"] += infoImage["dT"];
                    infoImage["height"] += infoImage["dH"];
                }
                 
                var deltaActive = false;   
                if (infoImage["dL"]!=0) { deltaActive = true; objImage.style.left = infoImage["left"] + "px"; }
                if (infoImage["dW"]!=0) { deltaActive = true; objImage.style.width = infoImage["width"] + "px"; }
                if (infoImage["dT"]!=0) { deltaActive = true; objImage.style.top = infoImage["top"] + "px"; }
                if (infoImage["dH"]!=0) { deltaActive = true; objImage.style.height = infoImage["height"] + "px"; }
                
                infoImage["step"]++;
                if (infoImage["step"]<infoImage["totalSteps"])
                {
                    if ((!deltaActive) && (infoImage["opacity"]==100))
                    {
                        // Fading complete and no more moving
                        //window.status += "T";
                        infoImage["step"] = infoImage["totalSteps"];
                        info["longTimeout"] = 1;
                        info["hEngine"] = window.setTimeout("SS_EngineCycle('" + containerName + "')", infoImage["time"]);
                    }
                    else
                    {
                        // Fading and/or moving
                        //window.status += "m";            
                        info["longTimeout"] = 0;
                        info["hEngine"] = window.setTimeout("SS_EngineCycle('" + containerName + "')", SS_EngineInterval);    
                    }
                }
                else
                {
                    nextImage = true;
                }                
            }
            
            if (nextImage)
            {
                if (info["imagescount"]==1) return;
                
                info["prevImage"] = info["currImage"];
                info["currImage"]++;
                if (info["currImage"]>=imagesLoaded) info["currImage"] = 0;
                if (info["currImage"]==info["prevImage"]) info["prevImage"] = -1;
                info["images"][info["currImage"]]["opacity"] = 0;
                info["images"][info["currImage"]]["step"] = 0;
                
                //window.status += "N";
                info["longTimeout"] = 0;
                info["hEngine"] = window.setTimeout("SS_EngineCycle('" + containerName + "')", SS_EngineInterval);
            }
        }       
    }
    else
    {
        // No image available
        //window.status += ".";
        info["longTimeout"] = 0;        
        info["hEngine"] = window.setTimeout("SS_EngineCycle('" + containerName + "')", SS_ImageLoaderInterval);
    }
    
    //if (window.status.length > 100) window.status = "";
}