/**
 * @copyright  Copyright(c) 2005-2009, IC Zones
 * @author     Michael Jolin
 * @since      2009,03,06
 * @package		JS
**/

/**
 * Object constructor
 *
 * @author		Michael Jolin
 * @since		2009,03,06
**/
ICZ.formJs = {
	originalColor: {},
	valumsAjaxUpload: 0,
	forValidation: {},
	captcha: null,

	setCaptcha: function( _id ) {
		google.setOnLoadCallback( function() {
				$.getScript( '/jsPlugins/jCap-2.0/md5.js', function() {
						$.getScript( '/jsPlugins/jCap-2.0/jcap.js', function() {
								ICZ.formJs.captcha = sjcap();
	
								ICZ.$( _id + 'Img' ).innerHTML = '<img width="150" src="/jsPlugins/jCap-2.0/cimg/' + ICZ.formJs.captcha.img + '" />';
								ICZ.$( _id + 'Input' ).innerHTML += '<input size="20" type="text" id="' + ICZ.formJs.captcha.id + '" />';
							});
					});
			});
	},

	init: function() {
		this.forValidation = arguments;

		var count = arguments.length;
		var elm = '';
		var val = '';

		for( var i=0; i<count; i++ ) {
			if( typeof( arguments[i] ) == 'object' ) {
				elm = $( '#' + arguments[i].name );
				if( arguments[i].max ) {
					val = arguments[i].max;
					elm.keydown( function( _e ) {
							if( ( _e.keyCode < 33 || _e.keyCode > 40 ) && _e.ctrlKey == false &&
									_e.keyCode != 8 && _e.keyCode != 27 && _e.keyCode != 45 && _e.keyCode != 46 ) {
								return ICZ.formJs.max( elm[0], val );
							}
						});
				}
			}
		}
	},

	/**
	 * Validate the form if is initiate
	**/
	submit: function() {
		var valid = true;
		var captcha = true;

		if( this.forValidation.length > 0 )
			valid = this.validate( 'fromSubmit', this.forValidation );
		if( this.captcha != null ) {
			var elm = $( '#' + this.captcha.id );
			if( elm.css( 'background-color' ) != 'rgb(255, 51, 51)' )
				this.originalColor[this.captcha.id] = elm.css( 'background-color' );

			captcha = jcap();
			elm.css( 'background-color', ( captcha == true ) ? this.originalColor[this.captcha.id] : 'rgb(255,51,51)' );
		}

		return ( valid && captcha );
	},

	/**
	 * Clear all input element
	**/
	clearAll: function() {
		$( 'input' ).each( function( i ) {
				if( this.type == 'text' )
					this.value = '';
			});
		$( 'textarea' ).each( function( i ) {
				this.value = '';
			});
	},

	/**
	 * Check if the user dont pass the max char
	**/
	max: function( _elm, _max ) {
		return ( _elm.value.length <= _max );
	},

	/**
	 * Validate each input of form
	**/
	validate: function() {
		if( arguments[0] == 'fromSubmit' )
			arguments = arguments[1];

		var count = arguments.length;
		var elm = '';
		var type = '';
		var valid = true;
		var oneValid = true;

		for( var i=0; i<count; i++ ) {
			if( typeof( arguments[i] ) == 'object' ) {
				elm = $( '#' + arguments[i].name );
				type = ( arguments[i].type ) ? arguments[i].type : 'text';
			} else {
				elm = $( '#' + arguments[i] );
				type = 'text';
			}

			if( elm.length > 0 ) {
				if( elm.css( 'background-color' ) != 'rgb(255, 51, 51)' )
					this.originalColor[arguments[i]] = elm.css( 'background-color' );

				oneValid = this.checkByType( elm[0], type );
				elm.css( 'background-color', ( oneValid ) ? this.originalColor[arguments[i]] : 'rgb(255,51,51)' );
				if( oneValid == false ) valid = false;
			} else {
				elm = $( "input[name='" + arguments[i] + "']" );
				if( elm.length > 0 ) {
					if( $( elm[0].parentNode ).css( 'background-color' ) != 'rgb(255, 51, 51)' )
						this.originalColor[arguments[i]] = $( elm[0].parentNode ).css( 'background-color' );

					switch( elm[0].type ) {
						case 'radio':
							if( $( "input[name='" + arguments[i] + "']:checked" ).length != 1 ) {
								for( var j=0; j<elm.length; j++ )
									$( elm[j].parentNode ).css( 'background-color', 'rgb(255,51,51)' );
								valid = false;
							} else {
								for( var j=0; j<elm.length; j++ )
									$( elm[j].parentNode ).css( 'background-color', this.originalColor[arguments[i]] );
							}
					}
				} else {
					alert( "Can't find : " + arguments[i] );
					valid = false;
				}
			}
		}

		return valid;
	},

	/**
	 * Check if the value is valid for each type
	**/
	checkByType: function( _elm, _type ) {
		var valid = true;

		switch( _type ) {
			case 'text':
				valid = ( _elm.value != '' );
				break;
			case 'email':
				valid = ( /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test( _elm.value ) );
				break;
		}

		return valid;
	},

	/**
	 * Attaches event to a dom element
	 */
	addEvent: function( el, type, fn ) {
		if( window.addEventListener ) {
			el.addEventListener( type, fn, false );
		} else if( window.attachEvent ) {
			var f = function() { fn.call( el, window.event ); };
			el.attachEvent( 'on' + type, f );
		}
	},

	fileFromPath: function( file ) {
		return file.replace(/.*(\/|\\)/, '' );
	},
	getExt: function( file ) {
		return ( /[.]/.exec( file ) ) ? /[^.]+$/.exec( file.toLowerCase() ) : '';
	},
	hasClass: function( ele, cls ) {
		return ele.className.match( new RegExp( '(\\s|^)' + cls + '(\\s|$)' ) );
	},
	addClass: function( ele, cls ) {
		if( !formJs.hasClass( ele, cls ) ) ele.className += ' ' + cls;
	},
	removeClass: function( ele, cls ) {
		var reg = new RegExp( '(\\s|^)' + cls + '(\\s|$)' );
		ele.className = ele.className.replace( reg,' ' );
	},
	/**
	 * Function generates unique id
	 */
	getUID: function() {
		return 'ValumsAjaxUpload' + this.valumsAjaxUpload++;
	},
	/**
	 * Creates and returns element from html chunk
	 */
	toElement: function( html ) {
		var div = document.createElement( 'div' );
		div.innerHTML = html;
		var el = div.childNodes[0];
		div.removeChild( el );
		return el;
	},
	getBox: function( el ) {
		var offset = $( el ).offset();

		return {
			left: offset.left,
			right: offset.left + el.offsetWidth,
			top: offset.top,
			bottom: offset.top + el.offsetHeight
		};
	}
};

// Please use AjaxUpload , Ajax_upload will be removed in the next version
AjaxUpload = function( button, options ) {
	this._input = null;
	this._button = $( '#' + button )[0];
	this._disabled = false;
	this._submitting = false;

	this._settings = {
			action: 'upload.php',		// Location of the server-side upload script
			name: 'userfile',				// File upload name
			data: {},						// Additional data to send
			autoSubmit: true,				// Submit file as soon as it's selected
			onChange: function( file, extension ){},	// When user selects a file, useful with autoSubmit disabled
			onSubmit: function( file, extension ){},	// Callback to fire before file is uploaded, You can return false to cancel upload
			onComplete: function( file, response ){}	// Fired when file upload is completed
		};

	// Merge the users options with our defaults
	for (var i in options)
		this._settings[i] = options[i];

	this._createInput();
	this._rerouteClicks();
}

// assigning methods to our class
AjaxUpload.prototype = {
	setData: function( data ) {
		this._settings.data = data;
	},
	disable: function() {
		this._disabled = true;
	},
	enable: function() {
		this._disabled = false;
	},
	// removes ajaxupload
	destroy: function() {
		if( this._input ) {
			if( this._input.parentNode ) {
				this._input.parentNode.removeChild( this._input );
			}
			this._input = null;
		}
	},

	/**
	 * Crossbrowser mouse coordinates
	 */
	 getMouseCoords: function( e ){
		// pageX/Y is not supported in IE
		// http://www.quirksmode.org/dom/w3c_cssom.html
		if( !e.pageX && e.clientX ) {
			return {
				x: e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft,
				y: e.clientY + document.body.scrollTop + document.documentElement.scrollTop
			};
		}

		return {
			x: e.pageX,
			y: e.pageY
		};
	},

	/**
	 * Creates invisible file input above the button 
	 */
	_createInput: function() {
		var self = this;
		var input = document.createElement( 'input' );
		input.setAttribute( 'type', 'file' );
		input.setAttribute( 'name', this._settings.name );
		var styles = {
			position: 'absolute',
			margin: '-5px 0 0 -175px',
			padding: 0,
			width: '220px',
			height: '10px',
			opacity: 0,
			cursor: 'pointer',
			display: 'none',
			zIndex: 2147483583
		};

		for( var i in styles ) {
			input.style[i] = styles[i];
		}

		// Make sure that element opacity exists
		// (IE uses filter instead)
		if( !( input.style.opacity === '0' ) ) {
			input.style.filter = 'alpha(opacity=0)';
		}
		document.body.appendChild( input );

		formJs.addEvent( input, 'change', function() {
			// get filename from input
			var file = formJs.fileFromPath( this.value );
			if( self._settings.onChange.call( self, file, formJs.getExt( file ) ) == false ) {
				return;
			}
			// Submit form when value is changed
			if( self._settings.autoSubmit ) {
				self.submit();
			}
		});

		this._input = input;
	},

	_rerouteClicks: function () {
		var self = this;
		var box, over = false;

		formJs.addEvent( self._button, 'mouseover', function( e ) {
				if( !self._input || over ) return;
				over = true;
				box = formJs.getBox( self._button );
			});

		// we can't use mouseout on the button,
		// because invisible input is over it
		formJs.addEvent( document, 'mousemove', function( e ) {
				var input = self._input;
				if( !input || !over ) return;
				if( self._disabled ) {
					formJs.removeClass( self._button, 'hover' );
					input.style.display = 'none';
					return;
				}
	
				var c = AjaxUpload.getMouseCoords( e );
	
				if( ( c.x >= box.left ) && ( c.x <= box.right ) && ( c.y >= box.top ) && ( c.y <= box.bottom ) ) {
					input.style.top = c.y + 'px';
					input.style.left = c.x + 'px';
					input.style.display = 'block';
					formJs.addClass( self._button, 'hover' );
				} else {
					// mouse left the button
					over = false;
					input.style.display = 'none';
					formJs.removeClass( self._button, 'hover' );
				}
			});
	},

	/**
	 * Creates iframe with unique name
	 */
	_createIframe: function() {
		// unique name
		// We cannot use getTime, because it sometimes return
		// same value in safari :(
		var id = formJs.getUID();

		// Remove ie6 "This page contains both secure and nonsecure items" prompt 
		// http://tinyurl.com/77w9wh
		var iframe = formJs.toElement( '<iframe src="javascript:false;" name="' + id + '" />' );
		iframe.id = id;
		iframe.style.display = 'none';
		document.body.appendChild( iframe );
		return iframe;
	},

	/**
	 * Upload file without refreshing the page
	 */
	submit: function() {
		var self = this, settings = this._settings;

		if( this._input.value === '' ) {
			return;	// there is no file
		}

		// get filename from input
		var file = formJs.fileFromPath( this._input.value );

		// execute user event
		if( !( settings.onSubmit.call( this, file, formJs.getExt( file ) ) == false ) ) {
			// Create new iframe for this submission
			var iframe = this._createIframe();

			// Do not submit if user function returns false
			var form = this._createForm( iframe );
			form.appendChild( this._input );
			form.submit();

			document.body.removeChild( form );
			form = null;
			this._input = null;

			// create new input
			this._createInput();

			var toDeleteFlag = false;
			formJs.addEvent( iframe, 'load', function() {
				if( iframe.src == 'about:blank' ){
					// First time around, do not delete.
					if( toDeleteFlag ) {
						// Fix busy state in FF3
						setTimeout( function() {
							document.body.removeChild( iframe );
						}, 0 );
					}
					return;
				}

				var doc = iframe.contentDocument ? iframe.contentDocument : frames[frames.length - 1].document;
				var response = doc.body.innerHTML;

				settings.onComplete.call( self, file, response );

				// Reload blank page, so that reloading main page
				// does not re-submit the post. Also, remember to
				// delete the frame
				toDeleteFlag = true;
				iframe.src = 'about:blank'; //load event fired
			});
		} else {
			// clear input to allow user to select same file
			this._input.value = '';
		}
	},

	/**
	 * Creates form, that will be submitted to iframe
	 */
	_createForm: function( iframe ) {
		var settings = this._settings;

		// method, enctype must be specified here
		// because changing this attr on the fly is not allowed in IE 6/7		
		var form = formJs.toElement( '<form method="post" enctype="multipart/form-data"></form>' );
		form.style.display = 'none';
		form.action = settings.action;
		form.target = iframe.name;
		document.body.appendChild( form );

		// Create hidden input element for each data key
		for( var prop in settings.data ) {
			var el = document.createElement( 'input' );
			el.type = 'hidden';
			el.name = prop;
			el.value = settings.data[prop];
			form.appendChild( el );
		}
		return form;
	}
};

if( typeof( google ) == 'object' ) {
	google.load( 'jquery', '1.3.1' );	// Load jQuery

	// on page load complete, fire off a jQuery json-p query
	// against Google web search
	google.setOnLoadCallback( function() {
		var elm = $( '#upload_button' );
		if( elm.length > 0 ) {
			new AjaxUpload( 'upload_button', {
					action: 'action/upload.php',
					name: 'uploadFormJs',
					onComplete: function( file, response ) {
							if( response == 'error' ) {
								alert( 'Error, please restart the upload' );
							} else {
								$( '#uploadFormJs' ).each( function( i ) {
										this.value = response;
									});
							}
						}
				});
		}
	});
}

