

//*************************
//  Title: Flicker Tooltip
//  Description: Scans the page for any links to photo pages on Flickr.com.
//  Creates tooltip previews of the images when the mouse 
//  hovers over the links.
//
//  Created on: Dec. 15, 2006
//  Last Modified: Dec 16, 2006
//  Version: 1.0.1 
//  Author: Aaron McBride
//
//  License: Public Domain
//  (the code and idea belongs to everyone 
//  maintain the attribution if you want)
//
//  Usage:
//  Place the following script tag in the <head> section of your web page:
//  <script type="text/javascript" src="http://path.to/flickr_tt.js"></script>
//
//  Add the following attribute to the <body> tag:
//  onload="ftt_init(apiKey)"
//  where "apiKey" is your Flickr apiKey
//  (available here: http://www.flickr.com/services/api/keys/ )
//  Hack the code to customize anything else.
//
//  Change log:
//  1.0.0 - Dec. 15, 2006 - Initial Release
//  1.0.1 - Dec. 16, 2006 - Fixed problem with IE not hiding the tt image at start 
//  1.0.2 - Dec. 17, 2006 - Fixed timing bug that could leave the tooltip visible
//  1.0.3 - Dec. 18, 2006 - Added caching of thumbnail url
//*************************

//offset of the tooltip from the mouse cursor
var ftt_offsetX = 15; 
var ftt_offsetY = 15;
//current mouse position
var ftt_mouseX = 0;
var ftt_mouseY = 0;

var ftt_apiKey = "";
var ftt_thumbUrlCache = new Object();

function ftt_init(apiKey)
{
    //init settings
    this.ftt_apiKey = apiKey;
    
    //create tt image element
    //<img id="flickr_tt" style="..." border="1" />
    var ttImg = document.createElement("img");
    ttImg.setAttribute("id", "flickr_tt");
    ttImg.setAttribute("style", "display:none;position:absolute;float:right;width:75;height:75;border-style:solid;border-width:thin;");
    ttImg.setAttribute("border", "1");
    document.body.appendChild(ttImg);
    //hack for IE to actually hide the image
    var thumb = document.getElementById('flickr_tt');
    if(thumb)
    {
        thumb.style.display = "none";
        thumb.onload = ftt_onimgload;
    }
        
    //look for anchor elements
    var anchors = document.getElementsByTagName('a');
    for(var i = 0; i < anchors.length; i++)
    {
        var aTag = anchors[i];
        //if the link href looks like a flickr photo page...
        if(ftt_getPhotoId(aTag.href))
        {
            //if it doesn't have onmouseover and onmouseoff events already
            if(!aTag.onMouseOver && !aTag.onMouseMove && !aTag.onMouseOut);
            {
                //add the events
                aTag.onmousemove = ftt_onmousemove;
                aTag.onmouseover = ftt_onmouseover;
                aTag.onmouseout = ftt_onmouseout;
            }
        }
    }
}//ftt_init(apiKey)

function ftt_showThumb(src)
{
    var thumb = document.getElementById('flickr_tt');
    if(thumb)
    {
        if(thumb.src == src)//already showing
            ftt_onimgload();
        else
            thumb.src = src;
    }
}//ftt_showThumb(src)

//JSON callback from Flickr
function jsonFlickrApi(rsp)
{
    var src = rsp.sizes.size[0].source;
    ftt_showThumb(src);
    var photoId = ftt_getPhotoId(src);
    if(photoId)
    {
        ftt_thumbUrlCache[photoId] = src;
    }
}

//Event Handlers:

//called when the mouse is moved over the link
//creates a script tag to load data from Flickr
//that code will call back to jsonFlickrApi
function ftt_onmouseover(e)
{
    ftt_getMouseXY(e);
    if (!e) e = window.event;
    var photoId = ftt_getPhotoId(e.target ? e.target : e.srcElement);
    var thumb = document.getElementById('flickr_tt');
    if(photoId && thumb)
    {
        if(ftt_thumbUrlCache[photoId])//if this photoId is cached
        {
            ftt_showThumb(ftt_thumbUrlCache[photoId]);
        }
        else
        {
            var src = "http://www.flickr.com/services/rest/?method=flickr.photos.getSizes&format=json&api_key=" + ftt_apiKey + "&photo_id=" + photoId;
            var flickrJS = document.createElement("script");
            flickrJS.setAttribute("src", src);
            document.body.appendChild(flickrJS);
        }
    }
}

//called when the mouse is moving over the link
//updates the position of the tooltip
function ftt_onmousemove(e)
{
    ftt_getMouseXY(e);
    var thumb = document.getElementById('flickr_tt');
    if(thumb)
    {
        thumb.style.position = 'absolute';
        thumb.style.left = ftt_mouseX + ftt_offsetX + "px";
        thumb.style.top = ftt_mouseY + ftt_offsetY + "px";
    }
}

//called whent he mouse moves off the link
//hides the tooltip
function ftt_onmouseout(e)
{
    var thumb = document.getElementById('flickr_tt');
    if(thumb)
        thumb.style.display = 'none';
}

//called whenever the thumb image loads
function ftt_onimgload()
{
    var thumb = document.getElementById('flickr_tt');
    if(thumb)
    {
        thumb.style.left = ftt_mouseX + ftt_offsetX + "px";
        thumb.style.top = ftt_mouseY + ftt_offsetY + "px";
        thumb.style.display = 'block';
    }
}

//Regex to find the photoId in a url
//returns false if the pattern doesn't match
function ftt_getPhotoId(url)
{
    var regex = /http:\/\/www.flickr.com\/photos\/(.+?)(\d+)/i;
    var matches = regex.exec(url);
    if(matches)
    {
        return matches[2];
    }
    else
    {
        regex = /http:\/\/static.flickr.com\/.+?\/(\d+)_(.*)/i;
        matches = regex.exec(url);
        if(matches)
            return matches[1];
    }
    return false;
}

//gets the current mouse potions (setting ftt_mouseX and ftt_mouseY)
//sample from http://dunnbypaul.net/js_mouse/
function ftt_getMouseXY(e) // works on IE6,FF,Moz,Opera7
{
    if (!e) e = window.event; // works on IE, but not NS (we rely on NS passing us the event)

    if (e)
    { 
        if (e.pageX || e.pageY)
        { // this doesn't work on IE6!! (works on FF,Moz,Opera7)
            ftt_mouseX = e.pageX;
            ftt_mouseY = e.pageY;
        }
        else if (e.clientX || e.clientY)
        { // works on IE6,FF,Moz,Opera7            
            ftt_mouseX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
            ftt_mouseY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
        }  
    }
}
