/**
 * Ajax upload
 * Project page - http://valums.com/ajax-upload/
 * Copyright (c) 2008 Andris Valums, http://valums.com
 * Licensed under the MIT license (http://valums.com/mit-license/)
 * Version 3.5 (23.06.2009)
 */

/**
 * Changes from the previous version: 1. Added better JSON handling that allows
 * to use 'application/javascript' as a response 2. Added demo for usage with
 * jQuery UI dialog 3. Fixed IE "mixed content" issue when used with secure
 * connections
 * 
 * For the full changelog please visit: http://valums.com/ajax-upload-changelog/
 */

(function() {

	var d = document, w = window;

	/**
	 * Get element by id
	 */
	function get(element) {
		if (typeof element == "string")
			element = d.getElementById(element);
		return element;
	}

	/**
	 * Attaches event to a dom element
	 */
	function addEvent(el, type, fn) {
		if (w.addEventListener) {
			el.addEventListener(type, fn, false);
		} else if (w.attachEvent) {
			var f = function() {
				fn.call(el, w.event);
			};
			el.attachEvent('on' + type, f)
		}
	}

	/**
	 * Creates and returns element from html chunk
	 */
	var toElement = function() {
		var div = d.createElement('div');
		return function(html) {
			div.innerHTML = html;
			var el = div.childNodes[0];
			div.removeChild(el);
			return el;
		}
	}();

	function hasClass(ele, cls) {
		return ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
	}
	function addClass(ele, cls) {
		if (!hasClass(ele, cls))
			ele.className += " " + cls;
	}
	function removeClass(ele, cls) {
		var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
		ele.className = ele.className.replace(reg, ' ');
	}

	// getOffset function copied from jQuery lib (http://jquery.com/)
	if (document.documentElement["getBoundingClientRect"]) {
		// Get Offset using getBoundingClientRect
		// http://ejohn.org/blog/getboundingclientrect-is-awesome/
		var getOffset = function(el) {
			var box = el.getBoundingClientRect(), doc = el.ownerDocument, body = doc.body, docElem = doc.documentElement,

			// for ie
			clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft
					|| body.clientLeft || 0,

			// In Internet Explorer 7 getBoundingClientRect property is treated
			// as physical,
			// while others are logical. Make all logical, like in IE8.

			zoom = 1;
			if (body.getBoundingClientRect) {
				var bound = body.getBoundingClientRect();
				zoom = (bound.right - bound.left) / body.clientWidth;
			}
			if (zoom > 1) {
				clientTop = 0;
				clientLeft = 0;
			}
			var top = box.top
					/ zoom
					+ (window.pageYOffset || docElem && docElem.scrollTop
							/ zoom || body.scrollTop / zoom) - clientTop, left = box.left
					/ zoom
					+ (window.pageXOffset || docElem && docElem.scrollLeft
							/ zoom || body.scrollLeft / zoom) - clientLeft;

			return {
				top : top,
				left : left
			};
		}

	} else {
		// Get offset adding all offsets
		var getOffset = function(el) {
			if (w.jQuery) {
				return jQuery(el).offset();
			}

			var top = 0, left = 0;
			do {
				top += el.offsetTop || 0;
				left += el.offsetLeft || 0;
			} while (el = el.offsetParent);

			return {
				left : left,
				top : top
			};
		}
	}

	function getBox(el) {
		var left, right, top, bottom;
		var offset = getOffset(el);
		left = offset.left;
		top = offset.top;

		right = left + el.offsetWidth;
		bottom = top + el.offsetHeight;

		return {
			left : left,
			right : right,
			top : top,
			bottom : bottom
		};
	}

	/**
	 * Crossbrowser mouse coordinates
	 */
	function getMouseCoords(e) {
		// pageX/Y is not supported in IE
		// http://www.quirksmode.org/dom/w3c_cssom.html
		if (!e.pageX && e.clientX) {
			// In Internet Explorer 7 some properties (mouse coordinates) are
			// treated as physical,
			// while others are logical (offset).
			var zoom = 1;
			var body = document.body;

			if (body.getBoundingClientRect) {
				var bound = body.getBoundingClientRect();
				zoom = (bound.right - bound.left) / body.clientWidth;
			}

			return {
				x : e.clientX / zoom + d.body.scrollLeft
						+ d.documentElement.scrollLeft,
				y : e.clientY / zoom + d.body.scrollTop
						+ d.documentElement.scrollTop
			};
		}

		return {
			x : e.pageX,
			y : e.pageY
		};

	}
	/**
	 * Function generates unique id
	 */
	var getUID = function() {
		var id = 0;
		return function() {
			return 'ValumsAjaxUpload' + id++;
		}
	}();

	function fileFromPath(file) {
		return file.replace(/.*(\/|\\)/, "");
	}

	function getExt(file) {
		return (/[.]/.exec(file)) ? /[^.]+$/.exec(file.toLowerCase()) : '';
	}

	// Please use AjaxUpload , Ajax_upload will be removed in the next version
	Ajax_upload = AjaxUpload = function(button, options) {
		if (button.jquery) {
			// jquery object was passed
			button = button[0];
		} else if (typeof button == "string" && /^#.*/.test(button)) {
			button = button.slice(1);
		}
		button = get(button);

		this._input = null;
		this._button = button;
		this._disabled = false;
		this._submitting = false;
		// Variable changes to true if the button was clicked
		// 3 seconds ago (requred to fix Safari on Mac error)
		this._justClicked = false;
		this._parentDialog = d.body;

		if (window.jQuery && jQuery.ui && jQuery.ui.dialog) {
			var parentDialog = jQuery(this._button).parents('.ui-dialog');
			if (parentDialog.length) {
				this._parentDialog = parentDialog[0];
			}
		}

		this._settings = {
			// Location of the server-side upload script
			action : 'upload.php',
			// File upload name
			name : 'userfile',
			// Additional data to send
			data : {},
			// Submit file as soon as it's selected
			autoSubmit : true,
			// The type of data that you're expecting back from the server.
			// Html and xml are detected automatically.
			// Only useful when you are using json data as a response.
			// Set to "json" in that case.
			responseType : false,
			// When user selects a file, useful with autoSubmit disabled
			onChange : function(file, extension) {
			},
			// Callback to fire before file is uploaded
			// You can return false to cancel upload
			onSubmit : function(file, extension) {
			},
			// Fired when file upload is completed
			// WARNING! DO NOT USE "FALSE" STRING AS A RESPONSE!
			onComplete : function(file, response) {
			}
		};

		// 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;
			}
		},
		/**
		 * Creates invisible file input above the button
		 */
		_createInput : function() {
			var self = this;
			var input = d.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' : '30px',
				'fontSize' : '14px',
				'opacity' : 0,
				'cursor' : 'pointer',
				'display' : 'none',
				'zIndex' : 2147483583
			// Max zIndex supported by Opera 9.0-9.2x
			// Strange, I expected 2147483647
			};
			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)";
			}

			this._parentDialog.appendChild(input);

			addEvent(input,
					'change',
					function() {
						// get filename from input
					var file = fileFromPath(this.value);
					if (self._settings.onChange.call(self, file, getExt(file)) == false) {
						return;
					}
					// Submit form when value is changed
					if (self._settings.autoSubmit) {
						self.submit();
					}
				});

			// Fixing problem with Safari
			// The problem is that if you leave input before the file select
			// dialog opens
			// it does not upload the file.
			// As dialog opens slowly (it is a sheet dialog which takes some
			// time to open)
			// there is some time while you can leave the button.
			// So we should not change display to none immediately
			addEvent(input, 'click', function() {
				self.justClicked = true;
				setTimeout(function() {
					// we will wait 3 seconds for dialog to open
						self.justClicked = false;
					}, 3000);
			});

			this._input = input;
		},
		_rerouteClicks : function() {
			var self = this;

			// IE displays 'access denied' error when using this method
		// other browsers just ignore click()
		// addEvent(this._button, 'click', function(e){
		// self._input.click();
		// });

		var box, dialogOffset = {
			top : 0,
			left : 0
		}, over = false;
		addEvent(self._button, 'mouseover', function(e) {
			if (!self._input || over)
				return;
			over = true;
			box = getBox(self._button);

			if (self._parentDialog != d.body) {
				dialogOffset = getOffset(self._parentDialog);
			}
		});

		// we can't use mouseout on the button,
		// because invisible input is over it
		addEvent(document, 'mousemove', function(e) {
			var input = self._input;
			if (!input || !over)
				return;

			if (self._disabled) {
				removeClass(self._button, 'hover');
				input.style.display = 'none';
				return;
			}

			var c = getMouseCoords(e);

			if ((c.x >= box.left) && (c.x <= box.right) && (c.y >= box.top)
					&& (c.y <= box.bottom)) {
				input.style.top = c.y - dialogOffset.top + 'px';
				input.style.left = c.x - dialogOffset.left + 'px';
				input.style.display = 'block';
				addClass(self._button, 'hover');
			} else {
				// mouse left the button
				over = false;
				if (!self.justClicked) {
					input.style.display = 'none';
				}
				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 = getUID();

		// Remove ie6 "This page contains both secure and nonsecure items"
		// prompt
		// http://tinyurl.com/77w9wh
		var iframe = toElement('<iframe src="javascript:false;" name="' + id + '" />');
		iframe.id = id;
		iframe.style.display = 'none';
		d.body.appendChild(iframe);
		return iframe;
	},
	/**
	 * Upload file without refreshing the page
	 */
	submit : function() {
		var self = this, settings = this._settings;

		if (this._input.value === '') {
			// there is no file
		return;
	}

	// get filename from input
	var file = fileFromPath(this._input.value);

	// execute user event
	if (!(settings.onSubmit.call(this, file, 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();

		d.body.removeChild(form);
		form = null;
		this._input = null;

		// create new input
		this._createInput();

		var toDeleteFlag = false;

		addEvent(iframe, 'load', function(e) {

			if (// For Safari
				iframe.src == "javascript:'%3Chtml%3E%3C/html%3E';" ||
				// For FF, IE
						iframe.src == "javascript:'<html></html>';") {

					// First time around, do not delete.
				if (toDeleteFlag) {
					// Fix busy state in FF3
				setTimeout(function() {
					d.body.removeChild(iframe);
				}, 0);
			}
			return;
		}

		var doc = iframe.contentDocument ? iframe.contentDocument
				: frames[iframe.id].document;

		// fixing Opera 9.26
		if (doc.readyState && doc.readyState != 'complete') {
			// Opera fires load event multiple times
			// Even when the DOM is not ready yet
			// this fix should not affect other browsers
			return;
		}

		// fixing Opera 9.64
		if (doc.body && doc.body.innerHTML == "false") {
			// In Opera 9.64 event was fired second time
			// when body.innerHTML changed from false
			// to server response approx. after 1 sec
			return;
		}

		var response;

		if (doc.XMLDocument) {
			// response is a xml document IE property
			response = doc.XMLDocument;
		} else if (doc.body) {
			// response is html document or plain text
			response = doc.body.innerHTML;
			if (settings.responseType
					&& settings.responseType.toLowerCase() == 'json') {
				// If the document was sent as 'application/javascript' or
				// 'text/javascript', then the browser wraps the text in a <pre>
				// tag and performs html encoding on the contents. In this case,
				// we need to pull the original text content from the text
				// node's
				// nodeValue property to retrieve the unmangled content.
				// Note that IE6 only understands text/html
				if (doc.body.firstChild
						&& doc.body.firstChild.nodeName.toUpperCase() == 'PRE') {
					response = doc.body.firstChild.firstChild.nodeValue;
				}
				if (response) {
					response = window["eval"]("(" + response + ")");
				} else {
					response = {};
				}
			}
		} else {
			// response is a xml document
			var response = doc;
		}

		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;

		// Fix IE mixed content issue
		iframe.src = "javascript:'<html></html>';";
	}	);

	} else {
		// clear input to allow user to select same file
		// Doesn't work in IE6
		// this._input.value = '';
		d.body.removeChild(this._input);
		this._input = null;

		// create new input
		this._createInput();
	}
},
/**
 * 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 = toElement('<form method="post" enctype="multipart/form-data"></form>');
		form.style.display = 'none';
		form.action = settings.action;
		form.target = iframe.name;
		d.body.appendChild(form);

		// Create hidden input element for each data key
		for ( var prop in settings.data) {
			var el = d.createElement("input");
			el.type = 'hidden';
			el.name = prop;
			el.value = settings.data[prop];
			form.appendChild(el);
		}
		return form;
	}
	};
})();

/*
 * Hilfsfunktionen
 */

function randomString(string_length) {
	var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
	var randomstring = '';
	for ( var i = 0; i < string_length; i++) {
		var rnum = Math.floor(Math.random() * chars.length);
		randomstring += chars.substring(rnum, rnum + 1);
	}
	return randomstring;
}

$(document)
		.ready(
				function() {

					rand_str = randomString(10);

					new AjaxUpload(
							'#button2',
							{
								action : 'upload.php?r=' + rand_str,
								onSubmit : function(file, ext) {
									if (ext
											&& /^(jpg|png|jpeg|gif|bmp)$/
													.test(ext)) {
										$('#example2 .text').text(
												'Übertrage "' + file + '" ...');
									} else {
										$('#example2 .text')
												.text(
														'Fehler: Nur Grafiken erlaubt!');
										return false;
									}
								},
								onComplete : function(file) {
									$('#example2 .text').html('<img src="uploads/'+rand_str+file.replace(/\s/g, "")+'" border="0" height="100" width="100" />');
									$('#uploadcontact').val(rand_str+file.replace(/\s/g, ""));
								}
							});

				});

