/* JS OOP
http://javascript.crockford.com/inheritance.html
http://javascript.crockford.com/private.html
*/


// fadeFlip object: fadeFlip(imgid);
function fadeFlip(imgid)
{
	// public vars
	this.imgid = imgid;
	this.fadesteptimeout = 100; // ms, default
	this.fadestep = 5;          // %, default

	// private vars
	var that = this,            // 'cause this might be something other than that ;-)
        preload = new Object(), // image "src" files
        fadestate,              // in|out|switch
        fliptoimage,            // the image to flip to
        imgobj,                 // img html element
        imgcont,                // container for img html element
        imgopacity = 100,       // start at not-transparent
        imgchk_max = 50,        // image-element has 5 seconds to load
        imgchk = 0;             // image-element-loaded check counter

	// run check
	checkImg();


	// privileged functions
	this.addImage = function (nr, src)
	{    // preload image
        if (nr == 1 || nr == 2)
        {
			preload[nr] = document.createElement('img');
			preload[nr].setAttribute('src', src);
        }
	}

	this.run = function ()
	{
		if (typeof(imgobj) == 'undefined')
		{	// checkImg() still running
			if (imgchk > imgchk_max)
			{	// checkImg() exceeded time limit: give up
				return false;
			}
			else
			{	// try again
				setTimeout(that.run, 50);
			}
		}
		else
        {   // attach event handlers
            // FUTURE: imgobj.onclick = that.click;    // open link
            imgobj.onmouseover = that.over; // flips to second image
            imgobj.onmouseout = that.out;   // flips back to first image

            // set stack
            imgobj.style.zIndex = '10';
		}
	}

    /* FUTURE: link
    this.click = function ()
    {
        alert('link');
    }
    */

    this.over = function ()
    {   // onmouseover
        imgobj.style.zIndex = '50'; // bring to front/top
        if (imgcont != false) imgcont.style.zIndex = '50';

        fliptoimage = 2;            // second image
        fadestate = 'out';          // begin by fading out
        that.flip();                // start cycle
    }

    this.out = function ()
    {   // onmouseout
        imgobj.style.zIndex = '10'; // move back/under
        if (imgcont != false) imgcont.style.zIndex = '10';

        fliptoimage = 1;            // first image
        fadestate = 'out';          // begin by fading out
        that.flip();                // (re)start cycle
    }

	this.flip = function ()
	{
		// apply effect
		if (fadestate == 'out')
		{	// fade out
			imgopacity -= that.fadestep;
			setOpacity(imgobj, imgopacity);

			// switch state
			if (imgopacity <= 0) fadestate = 'switch';
		}
		else if (fadestate == 'switch')
		{	// switch source file
			imgobj.setAttribute('src', preload[fliptoimage].getAttribute('src'));

			// switch state
			fadestate = 'in';
		}
		else if (fadestate == 'in')
		{	// fade in
			imgopacity += that.fadestep;
			setOpacity(imgobj, imgopacity);

			if (imgopacity >= 100)
			{	// end fade/flip
                /* IE7 sets partially transparent pixels to black in PNG's when/while:
                    "obj.style.filter = 'alpha(opacity:xxx)';"
                   is (being) applied. This can appear as an outline or
                   scratches in the image.
                   Setting the filter to none at least removes the
                   outline/scratches when the fading has completed. However, it
                   doesn't help whilst the fade is in progress.
                */
                imgobj.style.filter = 'none';

                // kill loop
                return false;
			}
		}

		// next loop
		window.setTimeout(that.flip, that.fadesteptimeout);
	}


	// private functions
	function checkImg()
	{	// check if target image exists and has loaded
		if (imgchk > imgchk_max)
		{	// really can't find it
			alert('Image: '+that.imgid+' not found!');
			return false;
		}
		else if (!document.getElementById(that.imgid))
		{	// try again
			imgchk++;
			window.setTimeout(checkImg, 100);
		}
		else
		{	// load complete
			imgobj = document.getElementById(that.imgid);

            // image contained within another element?
            imgcont = (document.getElementById(that.imgid+'_container')) ? document.getElementById(that.imgid+'_container') : false;
		}
	}

	function setOpacity(obj, opacity)
	{	// cross-browser opacity setter
		// source: http://clagnut.com/sandbox/imagefades/
		opacity = (opacity == 100) ? 99.999 : opacity;

		// IE/Win
		obj.style.filter = 'alpha(opacity:'+opacity+')';

		// Safari<1.2, Konqueror
		obj.style.KHTMLOpacity = opacity/100;

		// Older Mozilla and Firefox
		obj.style.MozOpacity = opacity/100;

		// Safari 1.2, newer Firefox and Mozilla, CSS3
		obj.style.opacity = opacity/100;
	}
} // end fadeFlip()
