/*
Sky.PrototypeExtensions
copyright by MySign AG (http://www.mysign.ch), Dominik Richner
depencies: Prototype 1.6.0.2
*/

// creating namespace
var Sky;
if ( !Sky ) Sky = {};


/*
 * Prototype.js : F I X
 * Check if we have an internet explorer version below 8, fastfix.
*/
Prototype.BrowserFeatures.ElementExtensions = (function() {
    	if( !!(window.attachEvent && navigator.userAgent.indexOf('Opera') === -1) &&
    			!navigator.appVersion.match( /8.\d+/ ) )
    	{
    		return !!window.HTMLElement;
    	}
    	else
    	{
    		if (window.HTMLElement && window.HTMLElement.prototype)
    			return true;
		    if (window.Element && window.Element.prototype)
		    	return true;
    	}
    })();


Sky.PrototypeExtensions = {
	// load the MySign Prototype extensions
	_REQUIRED_PROTOTYPE: '1.6.0.2',
	
	convertVersionString: function( versionString )
	{
		var r = versionString.split('.');
		while( r.length < 4 )
		{
			r[r.length] = 0;
		}
		return ( parseInt(r[0]) * 1000 ) + ( parseInt(r[1]) * 100 ) + ( parseInt(r[2]) * 10 ) + ( parseInt(r[3]) );
	},
	
	isPrototypeLoaded: function( version )
	{
		var returnValue = true;
		if( ( typeof Prototype == 'undefined' ) ||
			( typeof Element == 'undefined' ) ||
			( typeof Element.Methods == 'undefined' ) ||
			( Sky.PrototypeExtensions.convertVersionString(Prototype.Version) < Sky.PrototypeExtensions.convertVersionString(version) ) )
		{
			returnValue = false;
		}
		
		return returnValue;
	},
	
	isScriptaculousLoaded: function( version )
	{
		var returnValue = true;
		if( (  typeof Scriptaculous == 'undefined' ) ||
			( Sky.PrototypeExtensions.convertVersionString(Scriptaculous.Version) < Sky.PrototypeExtensions.convertVersionString(version) ) )
		{
			returnValue = false;
		}
		
		return returnValue;
	},
	
	isScriptaculousEffectsLoaded: function( version )
	{
		var returnValue = true;
		if( ( !Sky.PrototypeExtensions.isScriptaculousLoaded( version ) ) || 
			( typeof Effect == 'undefined' ) )
		{
			returnValue = false;
		}
		
		return returnValue;
	},
	
	isScriptaculousDragDropLoaded: function( version )
	{
		var returnValue = true;
		if( ( !Sky.PrototypeExtensions.isScriptaculousLoaded( version ) ) || 
			( typeof Droppables == 'undefined' ) ||
			( typeof Draggables == 'undefined' ) )
		{
			returnValue = false;
		}
		
		return returnValue;
	},
	
	load: function ()
	{
		// checking Prototype
		if( !Sky.PrototypeExtensions.isPrototypeLoaded( this._REQUIRED_PROTOTYPE ) )
		{
			throw( "Sky.PrototypeExtensions requires the Prototype JavaScript framework >= " + this._REQUIRED_PROTOTYPE );
		}
		
		Element.addMethods( this.ElementMethods );
		Element.addMethods( 'form', this.FormMethods );
		Element.addMethods( 'select', this.SelectMethods );
		Object.extend( String.prototype, this.StringMethods );
		
		Prototype.Browser.IE6 = Prototype.Browser.IE && parseInt(navigator.userAgent.substring(navigator.userAgent.indexOf("MSIE")+5)) === 6;
		Prototype.Browser.IE7 = Prototype.Browser.IE && parseInt(navigator.userAgent.substring(navigator.userAgent.indexOf("MSIE")+5)) === 7;
		Prototype.Browser.IE7up = Prototype.Browser.IE && !Prototype.Browser.IE6;
		Prototype.Browser.IE8up = Prototype.Browser.IE && !Prototype.Browser.IE6 && !Prototype.Browser.IE7;
	},
	
	SelectMethods: {
		mySelectOptionByValue: function ( element, value )
		{
			$A(element.options).each( function( option ) {
				option.selected = ( option.value == value );
			}.bind( value ) );
		},
		
		myClearOptions: function ( element )
		{
			for ( var i = 0; i < element.options.length; i++ )
			{
				element.options[i] = null;
			}
			element.options.length = 0;
		}
	},
	
	// Methods for form
	FormMethods: {
		// AJAX iframe request
		_myAIRequest_count: 0,
		myAIRequest: function ( form, opts )
		{
			var returnValue = true;
			
			// default options
			var options = {
				onComplete:		null
			}
			
			// extend the options
			Object.extend( options, opts || {} );
			
			form = $(form);
			
			Sky.PrototypeExtensions.FormMethods._myAIRequest_count++;
			var requestCount = Sky.PrototypeExtensions.FormMethods._myAIRequest_count;
			var iFrameContainerId = 'SkyPrototypeExtensions_FormMethods_myAIRequest_container_' + requestCount;
			var iFrameId = 'SkyPrototypeExtensions_FormMethods_myAIRequest_' + requestCount;
			
			var divContainer = new Element( 'div', { id: iFrameContainerId, style: 'display: none;' } ).update(
				new Element( 'iframe', { id: iFrameId, name: iFrameId, src: 'about:blank' } )
			);
			$(document.body).insert( { 'bottom': divContainer } );
			
			var loadedOptions = {
				iFrameContainerId: iFrameContainerId,
				iFrameId: iFrameId,
				onComplete: options.onComplete
			};
			Event.observe( iFrameId, 'load', Sky.PrototypeExtensions.FormMethods._myAIRequestLoaded.bind( loadedOptions ) );
			
			form.setAttribute( 'target', iFrameId );
			
			return returnValue;
		},
		_myAIRequestLoaded: function ()
		{
			if ( this.onComplete != null && Object.isFunction( this.onComplete ) )
			{
				var frame = $(this.iFrameId);
				var frameDocument = null;
        		if ( frame.contentDocument )
        		{
        			frameDocument = frame.contentDocument;
        		}
        		else if ( frame.contentWindow )
        		{
        			frameDocument = frame.contentWindow.document;
        		}
        		else
        		{
        			frameDocument = frame.document;
        		}
        		
        		if ( frameDocument != null && frameDocument.location.href != 'about:blank' )
        		{
        			this.onComplete( frameDocument.body.firstChild.innerHTML );
				}
			}
		}
	},
	
	// Methods for elements
	ElementMethods: {
		// clone a element
		// return cloned element
		_myDeepClone_count: 0,
		myDeepClone: function ( element, opts )
		{
			Sky.PrototypeExtensions.ElementMethods._myDeepClone_count++;
			var cloneCount = Sky.PrototypeExtensions.ElementMethods._myDeepClone_count;
			
			var returnValue = null;
			
			// default options
			var options = 
			{
				cloneIdPrefix:		'SkyPrototypeExtensions_myDeepClone_' + cloneCount + '_'
			}
			
			// extend the options
			Object.extend( options, opts || {} );
			
			element = $(element);
			
			// Clone the element
			returnValue = element.cloneNode( true );
			
			// If clonable element has ID attribute defined, modifying it to prevent duplicates
			if( returnValue.id )
			{
				returnValue.id = options.cloneIdPrefix + returnValue.id;
			}
			
			// Add prefix for IDs on all elements inside the clone
			returnValue.select( '*[id]' ).each( function( el )
												{
													if( el.id )
													{
														el.id = options.cloneIdPrefix + el.id;
													}
												} );
			
			// Insert clone
			element.parentNode.insertBefore( returnValue, element );
			returnValue.absolutize();
			
			var positionedOffset = element.positionedOffset();
			returnValue.setStyle( {
					zIndex: 10000 + cloneCount,
					position: 'absolute',
					top: positionedOffset.top + 'px',
					left: positionedOffset.left + 'px'
				} );
			
			return returnValue;
		},
		
		// update element with new content
		// return array:
		//		element		the updated html element
		//		script		the inserted script element
		_myUpdate_count: 0,
		myUpdate: function ( element, opts )
		{
			Sky.PrototypeExtensions.ElementMethods._myUpdate_count++;
			var updateCount = Sky.PrototypeExtensions.ElementMethods._myUpdate_count;
			
			var returnValue = {
				element:	element,
				script:		null
			};
			
			// default options
			var options = 
			{
				contentCode:		null,
				scriptTagId:		'SkyPrototypeExtensions_myUpdate_scriptcode_' + updateCount
			}
			
			// extend the options
			Object.extend( options, opts || {} );
			
			if ( options.contentCode != null && !Object.isUndefined( options.contentCode ) )
			{
				// update content without scripts
				returnValue.element = element.update( options.contentCode.stripScripts() )
				
				var scripts = options.contentCode.extractScripts().compact();
				if ( scripts != null && scripts.length > 0 )
				{
					var scriptTagText = scripts.join( '\n' ).replace( /<\!--/g, '' ).replace( /\/\/\s*-->/g, '' ).replace( /\/\/\s*<\!\[CDATA\[/g, '' ).replace( /\/\/\s*\]\]>/g, '' );
					var scriptTag = null;
					if( Prototype.Browser.IE )
					{
						scriptTag = document.createElement('script');
						scriptTag.type = 'text/javascript';
						scriptTag.text = scriptTagText;
						scriptTag.id = options.scriptTagId;
					}
					else
					{
						scriptTag = new Element( 'script', { type: 'text/javascript', id: options.scriptTagId } ).insert( scriptTagText );
					}
					
					$$('head')[0].appendChild( scriptTag );
					returnValue.script = $(options.scriptTagId);
				}
			}
			
			return returnValue;
		},
		
		// check element exists
		// return true or false
		myIsExisting: function ( id )
		{
			var returnValue = false;
			
			try
			{
				if( $(id) )
					returnValue = true;
			}
			catch ( e ) {}
			
			return returnValue;
		}
	},
	
	StringMethods: {
		/**
		 * Counts the number of appearances of a given string in the current one.
		 * 
		 * @param str  The string whichs appearance should be counted
		 */
		countAppearance: function( str )
		{
			var splitted = this.split( str );
			return splitted.length - 1;
		},

		/**
		 * Removes all special characters (not a-z0-9 and space) from the string
		 * 
		 * @param includeSpace  Flag if spaces should be excluded
		 */
		removeSpecialChars: function( includeSpace )
		{
			var re = /[^a-z0-9]+/gi;
			if( includeSpace )
			{
				re = /[^a-z0-9 ]+/gi;
			}
			
			return this.replace( re, '' );
		},
		
		/**
		 * Escapes the string by adding backslashes before \, ', " and 0 characters
		 */
		addSlashes: function()
		{
			return this.replace( /([\\"'])/g, '\\$1' ).replace( /\0/g, '\\0' );
		},
		
		/**
		 * Unescapes the string by removing the leading backslash before \, ', " and 0 characters
		 */
		stripSlashes: function()
		{
			return this.replace( /\0/g, '0' ).replace( /\\([\\'"])/g, '$1' );
		}
	}
};

Sky.PrototypeExtensions.load();

// For compatibility reasons
var My;
if( !My ) My = {};
My.PrototypeExtensions = Sky.PrototypeExtensions;