/*
Sky.IEpngFix 
copyright by MySign AG (http://www.mysign.ch), Dominik Richner
depencies: Prototype 1.6
*/
// creating namespace
var Sky;
if ( !Sky ) Sky = {};

Sky.IEpngFix = Class.create();

Sky.IEpngFix._REQUIRED_PROTOTYPE = '1.6.0.2';

Sky.IEpngFix.TAGS = [ 'a',
					 'input',
					 'select',
					 'textarea',
					 'button',
					 'iframe',
					 'object'
					];
Sky.IEpngFix.BLANKIMG = '/standard/img/empty.gif';
Sky.IEpngFix.CLASSNAME = 'skyIEpngFix';

Sky.IEpngFix.EVENT_PNGFIX_CHANGED = "Sky.IEpngFix:pngFixChanged";

Sky.IEpngFix.instance = null;

Sky.IEpngFix.prototype =
{
	initialize: function( opts ) 
	{
		// checking Prototype
		if( !Sky.PrototypeExtensions.isPrototypeLoaded( Sky.IEpngFix._REQUIRED_PROTOTYPE ) )
		{
			throw( "Sky.IEpngFix requires the Prototype JavaScript framework >= " + Sky.IEpngFix._REQUIRED_PROTOTYPE );
		}
		
		Event.observe( document, Sky.IEpngFix.EVENT_PNGFIX_CHANGED, this.launchPNGFix.bind( this ) );
		this.launchPNGFix();
		
		this.updateTimer = null;
		Event.observe( window, 'resize', function()
			{
				clearTimeout( this.updateTimer );
				this.updateTimer = setTimeout( this._update.bind( this ), 100 );
			}.bind( this )
		);
	},
	
	launchPNGFix: function ()
	{
		this.data = {};
		
		var elements = $$('.' + Sky.IEpngFix.CLASSNAME);
		for ( var i = 0; i < elements.length; i++ )
		{
			this._process( elements[i] );
		}
	},
	
	processPNGFix: function ( element )
	{
		this._process( element );
	},
	
	_process: function ( element )
	{
		element = $(element);
		var elementId = element.identify();
		
		if( !this.data[elementId] )
		{
			this.data[elementId] = { className: '' };
		}
		
		var data = this.data[elementId];
		data.className = element.className;
		
		var blank = Sky.IEpngFix.BLANKIMG.match(/([^\/]+)$/)[1];
		
		if ( element.src && { IMG: 1, INPUT: 1 }[element.nodeName] )
		{
			if ( (/\.png/i).test(element.src) )
			{
				this._fix( element, element.src, 2 );
			}
			else if ( element.src.indexOf(blank) == -1 )
			{
				this._fix( element, ' ' );
			}
		}
		
		var bgSrc = element.getStyle('backgroundImage');
		if ( ( bgSrc + element.src ).indexOf( blank ) == -1 )
		{
			var bgPNG = bgSrc.match(/url[("']+(.*\.png[^\)"']*)[\)"']/i);
			if ( bgPNG )
			{
				if ( !{ IMG: 1, INPUT: 1 }[element.nodeName] )
				{
					this._tileBg( element, bgPNG[1] );
					this._fix( element, '', 1 );
				}
				else
				{
					if ( data.tiles && data.tiles.src )
					{
						this._tileBg( element, '' );
					}
					this._fix( element, bgPNG[1], 1 );
				}
			}
			else
			{
				if ( data.tiles && data.tiles.src )
				{
					this._tileBg( element, '' );
				}
				this._fix( element, '' );
			}
		}
	},
	
	_fix: function ( element, src, t )
	{
		element = $(element);
		
		var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
		src = (src || '').replace(/\(/g, '%28').replace(/\)/g, '%29');
		
		if ( src && !(/IMG|INPUT/.test(element.nodeName) && (t != 2)) && element.currentStyle.width == 'auto' && element.currentStyle.height == 'auto' )
		{
			element.setStyle( {
				width: element.offsetWidth + 'px',
				height: element.clientHeight + 'px'
			} );
			
			if ( element.currentStyle.display == 'inline' )
			{
				element.setStyle( {
					display: 'inline-block'
				} );
			}
		}
		
		if ( t == 1 )
		{
			element.setStyle( {
				backgroundImage: 'url("' + Sky.IEpngFix.BLANKIMG + '")'
			} );
		}
		else if ( t == 2 )
		{
			element.src = Sky.IEpngFix.BLANKIMG;
		}
		
		if ( element.filters[f] )
		{
			element.filters[f].enabled = src ? true : false;
			if ( src )
			{
				element.filters[f].src = src;
			}
		}
		else if ( src )
		{
			element.setStyle( {
				filter: 'progid:' + f + '(enabled="true",src="' + src + '",sizingMethod="' + ( t == 2 ? 'scale' : 'crop' ) + '");'
			} );
		}
	},
	
	_tileBg: function ( element, pngSrc, ready )
	{
		element = $(element);
		var data = this.data[element.identify()];
		var elmW = Math.max( element.clientWidth, element.scrollWidth );
		var elmH = Math.max( element.clientHeight, element.scrollHeight );
		var bgX = element.currentStyle.backgroundPositionX;
		var bgY = element.currentStyle.backgroundPositionY;
		var bgR = element.currentStyle.backgroundRepeat;
		
		if ( !data.tiles )
		{
			data.tiles = {
							elm: element,
							src: '',
							cache: [],
							img: new Image(),
							old: {}
						 };
		}
		
		var tiles = data.tiles;
		var pngW = tiles.img.width;
		var pngH = tiles.img.height;
		
		if ( pngSrc )
		{
			if ( !ready && pngSrc != tiles.src )
			{
				Event.observe( tiles.img, 'load', function()
					{
						Event.stopObserving( tiles.img, 'load' );
						this._tileBg( element, pngSrc, 1 );
					}.bind( this )
				);
				return tiles.img.src = pngSrc;
			}
		}
		else
		{
			if ( tiles.src )
			{
				ready = 1;
			}
			pngW = pngH = 0;
		}
		
		tiles.src = pngSrc;
		
		if ( !ready && elmW == tiles.old.w && elmH == tiles.old.h && bgX == tiles.old.x && bgY == tiles.old.y && bgR == tiles.old.r )
		{
			return;
		}
		
		var pos = {
					top: '0%',
					left: '0%',
					center: '50%',
					bottom: '100%',
					right: '100%'
				  };
		var x = pos[bgX] || bgX;
		var y = pos[bgY] || bgY;
		var pc;
		
		if ( pc = x.match(/(\d+)%/) )
		{
			x = Math.round( ( elmW - pngW ) * ( parseInt( pc[1] ) / 100 ) );
		}
		if ( pc = y.match(/(\d+)%/) )
		{
			y = Math.round( ( elmH - pngH ) * ( parseInt( pc[1] ) / 100 ) );
		}
		x = parseInt( x );
		y = parseInt( y );
		
		var repeatX = { 'repeat': 1, 'repeat-x': 1 }[bgR];
		var repeatY = { 'repeat': 1, 'repeat-y': 1 }[bgR];
		
		if ( repeatX )
		{
			x %= pngW;
			if ( x > 0 )
			{
				x -= pngW;
			}
		}
		
		if ( repeatY )
		{
			y %= pngH;
			if ( y > 0 )
			{
				y -= pngH;
			}
		}
		
		if ( !( { relative: 1, absolute: 1 }[element.currentStyle.position] ) )
		{
			element.setStyle( {
				position: 'relative'
			} );
		}
		
		var count = 0;
		var maxX = repeatX ? elmW : x + 0.1;
		var maxY = repeatY ? elmH : y + 0.1;
		
		var xPos, yPos, d, s, isNew;
		
		if ( pngW && pngH )
		{
			for ( xPos = x; xPos < maxX; xPos += pngW )
			{
				for ( yPos = y; yPos < maxY; yPos += pngH )
				{
					isNew = 0;
					if ( !tiles.cache[count] )
					{
						tiles.cache[count] = document.createElement('div');
						isNew = 1;
					}
					var clipR = ( xPos + pngW > elmW ? elmW - xPos : pngW );
					var clipB = ( yPos + pngH > elmH ? elmH - yPos : pngH );
					
					d = tiles.cache[count];
					
					s = d.style;
					s.behavior = 'none';
					s.left = xPos + 'px';
					s.top = yPos + 'px';
					s.width = clipR + 'px';
					s.height = clipB + 'px';
					s.clip = 'rect(' + ( yPos < 0 ? 0 - yPos : 0 ) + 'px,' + clipR + 'px,' + clipB + 'px,' + ( xPos < 0 ? 0 - xPos : 0 ) + 'px)';
					s.display = 'block';
					
					if ( isNew )
					{
						s.position = 'absolute';
						s.zIndex = -999;
						if ( element.firstChild )
						{
							element.insertBefore( d, element.firstChild );
						}
						else
						{
							element.appendChild( d );
						}
					}
					this._fix( d, pngSrc, 0 );
					count++;
				}
			}
		}
		
		while ( count < tiles.cache.length )
		{
			this._fix( tiles.cache[count], '', 0 );
			$(tiles.cache[count++]).setStyle( {
				display: 'none'
			} );
		}
		
		tiles.old = {
						w: elmW,
						h: elmH,
						x: bgX,
						y: bgY,
						r: bgR
					};
	},
	
	_update: function ()
	{
		for ( var i in this.data )
		{
			var t = this.data[i].tiles;
			if ( t && t.elm && t.src )
			{
				this._tileBg( t.elm, t.src );
			}
		}
	}
};

if( Prototype.Browser.IE && !Prototype.Browser.IE7up )
{
	Event.observe( document, 'dom:loaded', function(){ Sky.IEpngFix.instance = new Sky.IEpngFix(); } );
}
