// @name      Random Image Loader
// @namespace http://chapnickman.com/demo/randomimage/
// @version   1.0 RC3
// @author    Nick Chapman

RandomImage._instances = new Array();

function RandomImage(callback, preloadImages, autoShowSeconds, uniqueKey)
{
    if (callback)
    {
        this.callback = callback;
        this.preloadImages = preloadImages;
        
        if (autoShowSeconds != null && autoShowSeconds > 0)
            this.autoShowSeconds = autoShowSeconds;
        else
            this.autoShowSeconds = 0;
            
        this.uniqueKey = uniqueKey;
            
        this.currentIndex = 0;
        this.orderedList = new Array();
        
        this.index = RandomImage._instances.length;
	
	    RandomImage._instances[this.index] = this;
    }
    else
    {
        alert("No callback defined");
    }
}

RandomImage.prototype.loadFromXml = function(xmlFilePath)
{
    this.loadXmlDocument(xmlFilePath, RandomImage.parseStandardXml);
}

RandomImage.prototype.loadFromCustomXml = function(xmlFilePath, callback)
{
    this.loadXmlDocument(xmlFilePath, callback);
}

RandomImage.prototype.load = function()
{
    this.getRandomStartIndex();
    this.nextImage(this.autoShowSeconds > 0);
    this.startPreLoadImages();
}

RandomImage.prototype.loadXmlDocument = function(url, callback)
{
    var xmlRequest = null;
    var instance = this;
    
    if (window.XMLHttpRequest)
    {
        xmlRequest = new XMLHttpRequest();
    }
    else if (window.ActiveXObject)
    {
        xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");
    }
    
    if (xmlRequest)
    {
        xmlRequest.onreadystatechange = function()
        {
            instance.processRequestChange(xmlRequest, callback);
        }
        
        xmlRequest.open("GET", url, true);
        xmlRequest.send(null);
    }
}

RandomImage.prototype.processRequestChange = function(xmlRequest, callback)
{
    if (xmlRequest.readyState == 4)
    {
        if (xmlRequest.status == 200)
        {
            callback.call(this, this, xmlRequest.responseXML);
            
            this.getRandomStartIndex();
            this.nextImage(this.autoShowSeconds > 0);
            this.startPreLoadImages();
        }
        else
        {
            alert("There was a problem retrieving the XML data:\n" + xmlRequest.statusText);
        }
    }
}

RandomImage.prototype.addImage = function(imageUrl, description)
{
    var newImage = new Object();
    
    newImage.src = imageUrl;
    newImage.description = description;
    
    this.orderedList[this.orderedList.length] = newImage;
}

RandomImage.prototype.getRandomStartIndex = function()
{
    this.currentIndex = Math.round(Math.random() * (this.orderedList.length - 1));
}

RandomImage.prototype.autoAdvance = function(seconds)
{
    if (seconds != null && seconds > 0)
        this.autoShowSeconds = seconds;
    else
        this.autoShowSeconds = 10;
        
    this.nextImage(true);
}

RandomImage.prototype.stopAutoAdvance = function(seconds)
{
    this.autoShowSeconds = 0;
}

RandomImage.prototype.nextImage = function(auto, fromTimeout)
{
    if (!(this.autoShowSeconds == 0 && fromTimeout))
    {
        if ((this.currentIndex + 1) == this.orderedList.length)
        {
            this.currentIndex = 0;
        }
        else
        {
            this.currentIndex++;
        }
        
        this.callback.call(this, this.orderedList[this.currentIndex].src, this.orderedList[this.currentIndex].description, this.uniqueKey);
        
        if (auto && this.autoShowSeconds > 0)
            setTimeout("RandomImage._instances[" + this.index + "].nextImage(true, true)", this.autoShowSeconds * 1000);
    }
}

RandomImage.prototype.previousImage = function(auto)
{    
    if ((this.currentIndex - 1) < 0)
    {
        this.currentIndex = this.orderedList.length - 1;
    }
    else
    {
        this.currentIndex--;
    }
    
    this.callback.call(this, this.orderedList[this.currentIndex].src, this.orderedList[this.currentIndex].description, this.uniqueKey);
}

RandomImage.prototype.startPreLoadImages = function()
{
    if (this.preloadImages)
        setTimeout("RandomImage._instances[" + this.index + "].preLoadImages()", 0);
}

RandomImage.prototype.preLoadImages = function()
{
    for (var i = 0; i < this.orderedList.length; i++)
    {
        var image = new Image();
        
        image.src = this.orderedList[i].src;
    }
}

RandomImage.parseStandardXml = function(instance, node)
{
    var pictureNodes = node.getElementsByTagName("picture");

    for (var i = 0; i < pictureNodes.length; i++)
    {
        var url;
        var description;

        try
        {
            url = pictureNodes[i].getAttribute("url");
            description = pictureNodes[i].getAttribute("description");
        }
        catch (e){}

        instance.addImage(url, description);
    }
}

RandomImage.parseFlickrRss = function(instance, node)
{
    var itemNodes = node.getElementsByTagName("item");
    
    for (var i = 0; i < itemNodes.length; i++)
    {
        var url;
        var description;
        
        try
        {
            var xmlDescription = itemNodes[i].getElementsByTagName("description")[0].firstChild.nodeValue;
            
            imgMatch = /http:\/\/photos\d+\.flickr\.com\/[^\.]+\.jpg/.exec(xmlDescription);
            nameMatch = /<a href="http:\/\/www.flickr.com\/people\/\w+\/">[^<]+<\/a>/.exec(xmlDescription);
            
            url = imgMatch[0].replace(/_m\./, ".");
            description = "Photo posted by " + nameMatch[0];
        }
        catch (e){}

        instance.addImage(url, description);
    }
}