if(!window.console) { window.console = { log: function(msg) { return; alert(msg); } }; }

var PRINTO = {};

PRINTO.App = function() {
	var overlay = false;
	var video = false;
	
	function attachLoginFormObservers() {
		var form = $('login_box').down('form');
		if(form) form.observe('submit', submitLoginForm);
	}

	function attachLogoutLinkObservers() {
		var link = $('logout_link');
		if(link) {
			link.observe('click', function(event) {
				Event.stop(event);
				new Ajax.Request(link.href);
			});
		}
	}
	
	function submitLoginForm(event) {
		Event.stop(event);
		new Ajax.Request(this.action, { parameters: Form.serialize(this)+'&sid='+window._upload_session_id });
	}
	
	function playDemoVideo(event) {
		Event.stop(event);
		// create the overlay
		if(!overlay) overlay = createOverlay();
		overlay.setStyle({ 'width': document.body.getWidth()+'px', 'height': document.body.getHeight()+'px' }).visualEffect('appear', { duration: 0.5, to: 0.7 });
		
		if(!video) video = createVideo();
		video.setStyle({ 
			'left': (document.viewport.getWidth()/2-320)+'px', 
			'top': ((document.viewport.getHeight()/2-172)+document.viewport.getScrollOffsets().top)+'px' 
		}).show();
	}
	
	function createOverlay() {
		var overlay = new Element('div', { 'class': 'overlay' });
		overlay.hide().setStyle({ 'position': 'absolute', 'top': '0', 'left': '0', 'backgroundColor': '#000000', 'zIndex': 1000 });
		$(document.body).insert({ top: overlay });
		overlay.observe('click', closeVideoOverlay);
		return overlay;
	}
	
	function closeVideoOverlay() {
		overlay.hide();
		video.hide();
	}
	
	function createVideo() {
		var video = new Element('div', { 'class': 'video' });
		var controls = new Element('div', { 'class': 'controls' });
		var closeButton = new Element('a', { 'href': '#', 'class': 'close' }).update('затвори');
		var helpButton = new Element('a', { 'href': '/help', 'class': 'help', 'target': '_blank' }).update('Прегледай страницата с въпроси и отговори.');
		controls.insert(helpButton);
		controls.insert(closeButton);
		
		var videoContainer = new Element('div', { 'id': 'demo_video' });
		videoContainer.update('<a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a>');
		video.hide().setStyle({ 'position': 'absolute', 'top': '0', 'left': '0', 'zIndex': 1001 }).insert(videoContainer);
		video.insert(controls);
		
		closeButton.observe('click', closeVideoOverlay);
		
		$(document.body).insert({ top: video });
		
		var flashvars = {};
		flashvars.autostart = "true";
		
		var params = {};
		params.quality = "best";
		params.scale = "showall";
		params.wmode = "opaque";
		params.bgcolor = "#000000";
		params.allowscriptaccess = "always";
		
		var attributes = {};
		attributes.id = "flash_demo_video";
		swfobject.embedSWF("/images/printo-demo-video.swf", "demo_video", "640", "344", "9.0.0", "/images/expressInstall.swf", flashvars, params, attributes);
		
		return video;	
	}
	
	return {
		initialize: function() {
			PRINTO.PHOTO_TEMPLATE = $('photo_template');
			
			PRINTO.PhotoManager.initialize();
			PRINTO.OrderManager.initialize();
			PRINTO.Taskbar.initialize();
			attachLoginFormObservers();
			attachLogoutLinkObservers();
			// TODO: preload images
			// Hijack Video link
			$$('#video a').invoke('observe', 'click', playDemoVideo);
		},
		
		attachLoginFormObservers: attachLoginFormObservers,
		
		attachLogoutLinkObservers: attachLogoutLinkObservers,
		
		destroy: function() {
			
		},
		
		focusLogin: function() {
			if($('login_box')) {
				new Effect.ScrollTo('login_box', { offset: -50, afterFinish: function() {
					$('email').focus();
				} });
				(function() { new Effect.Highlight('login_box'); }).delay(0.6);
			}
		}
	};
}();

PRINTO.PhotoManager = function() {
	// PRIVATE PROPERTIES
	var ALLOWED_FILETYPES = '*.jpg;*.jpeg;*.png;*.tif;*.tiff';
  var MAX_UPLOAD_SIZE = "35 MB";
	
  var uploaderContainer;
  var uploader;
  var uploadButton;
  var uploadSessionId;
  var photosContainer;
  
  // PRIVATE METHODS
	function setupUploader() {
		var settings = {
			upload_url: 								'/files/upload',
			flash_url: 									'/images/swfupload.swf',
			file_size_limit: 						MAX_UPLOAD_SIZE,
			file_types: 								ALLOWED_FILETYPES,
			file_types_description: 		'Снимки', // TODO: Localize
			post_params: 								{ 'sid': uploadSessionId, 'request_prices': '1' },
			
			button_placeholder_id:			'upload_button',
			button_image_url:						'/images/button-upload.png',
			button_cursor: 							SWFUpload.CURSOR.HAND,
			button_width:								266,
			button_height:							120,
			button_window_mode:					SWFUpload.WINDOW_MODE.OPAQUE,
			
 			file_queued_handler: 				fileQueued,
 			file_queue_error_handler: 	fileQueueError,
 			file_dialog_complete_handler: fileDialogComplete, 
 			upload_start_handler: 			uploadStart, 
 			upload_progress_handler: 		uploadProgress, 
 			upload_error_handler: 			uploadError,
 			upload_success_handler: 		uploadSuccess,
 			upload_complete_handler: 		uploadComplete
		};
		
		uploader = new SWFUpload(settings);
	}
	
	function setSessionId(id) {
    uploadSessionId = id;
    
    // make sure we're not overwriting a cached session
    new Ajax.Request('/welcome/announce/'+id);
	}
	
	function addObservers() {
		uploadButton.observe('click', function(event) { Event.stop(event); uploader.selectFiles(); });
	}
	
	function fileQueued(file) {
		//console.log('fileQueued', file);		
		
		var uploadId = uploadSessionId+file.id;
		uploader.addFileParam(file.id, 'upload_id', uploadId);
		PRINTO.PHOTOS[uploadId] = new PRINTO.Photo(file, uploadId);
	}
	
	function fileQueueError(file, errorCode, message)  {
		try {
			switch (errorCode) {
			case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED:
				alert("You have attempted to queue too many files.\n" + (message === 0 ? "You have reached the upload limit." : "You may select " + (message > 1 ? "up to " + message + " files." : "one file.")));
				return;
			case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
				alert("The file you selected is too big.");
				//console.log("Error Code: File too big, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
				return;
			case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
				alert("The file you selected is empty.  Please select another file.");
				//console.log("Error Code: Zero byte file, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
				return;
			case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
				alert("The file you choose is not an allowed file type.");
				//console.log("Error Code: Invalid File Type, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
				return;
			default:
				alert("An error occurred in the upload. Try again later.");
				//console.log("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
				return;
			}
		} catch (e) {
		}
	}
	
	function fileDialogComplete(numFilesSelected, numFilesQueued) {
		//console.log('fileDialogComplete', numFilesSelected, numFilesQueued);		
		
		if(numFilesQueued > 0) {
			uploader.startUpload();
		}
	}
	
	function uploadStart() {
		//console.log('uploadStart');
	}
	
	function uploadProgress(file, bytesLoaded, bytesTotal) {
		//console.log('uploadProgress', file, bytesLoaded, bytesTotal);
		getPhoto(file.id).setUploadStatus(bytesLoaded, bytesTotal);
	}
	
	function uploadError(file, errorCode, message) {
		//console.log('uploadError', file, errorCode, message);
		
		try {
			switch (errorCode) {
			case SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL:
				alert("There was a configuration error.  You will not be able to upload a resume at this time.");
				//console.log("Error Code: No backend file, File name: " + file.name + ", Message: " + message);
				return;
			case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
				alert("You may only upload 1 file.");
				//console.log("Error Code: Upload Limit Exceeded, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
				return;
			case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
			case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
				break;
			default:
				alert("An error occurred in the upload. Try again later.");
				//console.log("Error Code: " + errorCode + ", File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
				return;
			}
	
			switch (errorCode) {
			case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:
				//console.log("Error Code: HTTP Error, File name: " + file.name + ", Message: " + message);
				break;
			case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:
				//console.log("Error Code: Upload Failed, File name: " + file.name + ", File size: " + file.size + ", Message: " + message);
				break;
			case SWFUpload.UPLOAD_ERROR.IO_ERROR:
				//console.log("Error Code: IO Error, File name: " + file.name + ", Message: " + message);
				break;
			case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:
				//console.log("Error Code: Security Error, File name: " + file.name + ", Message: " + message);
				break;
			case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
				//console.log("Error Code: Upload Cancelled, File name: " + file.name + ", Message: " + message);
				break;
			case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
				//console.log("Error Code: Upload Stopped, File name: " + file.name + ", Message: " + message);
				break;
			}
		} catch (ex) {
		}
	}
	
	function uploadSuccess(file, serverData) {
		//console.log('uploadSuccess', file, serverData);
		(function() { window.eval(serverData); }).defer();
	}
	
	function uploadComplete(file) {
		//console.log('uploadComplete', file);
		uploader.removePostParam('request_prices');
	}
	
	function getPhoto(id) {
		return PRINTO.PHOTOS[uploadSessionId+id];
	}
	
	// PUBLIC METHODS
	return {
		initialize: function() {
			uploaderContainer = $('uploader_container');
			uploadButton = $('upload_button');
			PRINTO.PhotoManager.photosContainer = $('photos');
			setSessionId(window._upload_session_id);
			setupUploader();
			addObservers();
		},
		
	  getSessionId: function() {
	    return uploadSessionId;
	  },
	  
	  getPhoto: function(id) {
	  	return getPhoto(id);
	  },
	  
		uploadedPhotos: function() {
			return $H(PRINTO.PHOTOS).values().select(function(photo) { return photo.isUploaded() && !photo.isSuspended(); });
		},
	  		
		destroy: function() {
			uploadButton.stopObserving('click');
			
			uploaderContainer = null;
			uploadButton = null;
		}
	};
}();

PRINTO.OrderManager = function() {
	var PRICES;
	var pricePerSqMeter;
	var active = false;
	var usePoints = false;
	var shippingCosts = 0;
	var pointsUsed = 0;
	var pointValue;
	var discountLimit;
	var totalPrice = 0;
	var totalPriceVat = 0;
	var vatFactor = 1.2;
	var cashOnDeliveryLimit = false;
	var codFee;
	var startOrderButton;
	var completeOrderButton;
	var orderForm;
	var recipientForm;
	var invoiceForm;
	var codOption;
	var summaryTotalPrice;
	var shippingCostsContainer;
	var submitInProgress = false;
	var active = false;
	
	function showStartOrderButton() {
		startOrderButton.up().removeClassName('hide');
	}
	
	function showShippingCostsContainer() {
		(shippingCostsContainer || createShippingCostsContainer()).show();
	}
	
	function createShippingCostsContainer() {
		shippingCostsContainer = new Element('p', { id: 'shipping_costs_explanation', 'class': 'notice' });
		shippingCostsContainer.insert('Разходи по доставката: <span></span>');
		shippingCostsContainer.hide();
		
		$('delivery_info').down('fieldset').insert(shippingCostsContainer);
		return shippingCostsContainer;
	}
	
	function getCodOption() {
		return codOption || $('payment_type_1').up('div');
	}
	
	function showCodOption() {
		if(	getDeliveryType() !== 'standart' 
				&& totalPriceVat < (cashOnDeliveryLimit || (totalPriceVat+1)) 
				&& $F('use_recipient_form') != '1') {
			getCodOption().show();
		}
	}
	
	function hideCodOption() {
		getCodOption().hide();
	}
	
	function getDeliveryType() {
		//var selectedDeliveryType = $A([$('order_type_1'), $('order_type_2'), $('order_type_3')]).detect(function(el) { return el.checked; });
		var selectedDeliveryType = $A([$('order_type_1'), $('order_type_2')]).detect(function(el) { return el.checked; });
		
		return selectedDeliveryType ? selectedDeliveryType.value : false;
	}

	function getPaymentType() {
		var selectedPaymentType = $A([$('payment_type_1'), $('payment_type_2')]).detect(function(el) { return el.checked; });
		
		return selectedPaymentType ? selectedPaymentType.value : false;
	}
	
	function getCity() {
		return $F('order_city');
	}
	
	function startOrder(event) {
		Event.stop(event);
		
		var uploadedPhotos = PRINTO.PhotoManager.uploadedPhotos();
		
		if(uploadedPhotos.length == 0) {
			alert('Tрябва да качиш поне една снимка.');
			Effect.ScrollTo('steps');
			
			return false;
		}
		
		var parameters = uploadedPhotos.collect(function(photo) {
			return 'photo['+photo.uploadId+']='+photo.copies+'|'+photo.getPrintSizeIndex();
		});
		parameters.push('sid='+window._upload_session_id);
	
		new Ajax.Request('/welcome/order', { parameters: parameters.join('&') });
		active = true;
	}
	
	function attachFormObservers() {
		orderForm = $('order');
		invoiceForm = $('invoice_form');
		recipientForm = $('recipient_form');
		completeOrderButton = $('complete_order_button');
		
		$$('#delivery_info input').invoke('observe', 'click', changeDeliveryType);
		$$('#payment_info div input').invoke('observe', 'click', changePaymentType);
		
		$('order_city').observe('change', changeCity);
		$('use_recipient_form').observe('click', toggleRecipientForm);
		$('use_invoice_form').observe('click', toggleInvoiceForm);
		
		document.observe('printo:pricechanged', function(event) { 
			(summaryTotalPrice || (summaryTotalPrice = $('summary').down('.price'))).update(event.memo+' <span>лв</span>');
		});
		
		completeOrderButton.observe('click', completeOrder);
	}
	
	function changeDeliveryType(event) {
		var explanationParagraph = Event.element(event).up('p').next('p');
		explanationParagraph.up('fieldset').select('.explanation').invoke('hide');
		explanationParagraph.show();
		
		calculateShippingCosts();
		
		// when we have the regular delivery method (postal)
		// ePay becomes the only payment option
		if(getDeliveryType() == 'standart') {
			hideCodOption();
			$('payment_type_2').checked = 'checked';
			$('payment_type_2').up().next('p').show();
		} else {
			showCodOption();
		}
	}
	
	function changePaymentType(event) {
		var explanationParagraph = Event.element(event).up('p').next('p');
		explanationParagraph.up('fieldset').select('.explanation').invoke('hide');
		explanationParagraph.show();
		
		PRINTO.OrderManager.recalculatePrice();
	}
	
	function changeCity(event) {
		var selectedCity = this.value;
		
		// hide unavailable delivery types for cities outside Sofia
		//if(selectedCity != 'София') {
		//	// in case the user has already selected the fastest
		//	// available option, revert to type 2 (express)
		//	if($('order_type_3').checked)
		//		$('order_type_2').checked = "checked";
		//		
		//	$('order_type_3').up('div').hide();
		//}
		//else {
		//	$('order_type_3').up('div').show();
		//}
	}
	
	function completeOrder(event) {
		Event.stop(event);
		if(submitInProgress) {
			return false;
		}
		
		if(!validateOrderForm()) {
			return false;
		}
		
		// make sure the user hasn't deleted all of his photos
		if(!PRINTO.PHOTOS || !(PRINTO.PhotoManager.uploadedPhotos().length)) {
			alert('Tрябва да качиш поне една снимка');
			new Effect.ScrollTo('wrapper');
			return false;
		}
		
		// sent the finalized form to the server
		submitInProgress = true;
		var parameters = Form.serialize('order');
		parameters += '&sid='+window._upload_session_id;
		
		//console.log(parameters);
		new Ajax.Request('/welcome/complete', { parameters: parameters });
	}
	
	function validateOrderForm() {
		var form = $('order');
		var validationMap = {
			'order_first_name': 'notempty|name',
			'order_last_name': 'notempty|name',
			'order_phone': 'notempty|phone',
			'order_email': 'notempty|email',
			'order_address': 'notempty'
		};
		
		if($F('use_recipient_form') === '1') {
			validationMap = $H(validationMap).merge({
				'recipient_first_name': 'notempty|name',
				'recipient_last_name': 'notempty|name',
				'recipient_phone': 'notempty|phone',
				'recipient_address': 'notempty'
			});
		}
		
		if(!PRINTO.Validator.validate(validationMap)) {
			cleanPreviousErrors();
			showValidationErrors();
			Effect.ScrollTo('personal_info', { offset: -100 });
			return false;
		}
		
		// check if user has selected an order type
		//var orderTypes = $A([$('order_type_1'), $('order_type_2'), $('order_type_3')]);
		var orderTypes = $A([$('order_type_1'), $('order_type_2')]);
		
		var checked = function(el) { return el.checked; };
		if(!orderTypes.any(checked)) {
			cleanPreviousErrors();
			var errorHtml = buildErrorHtml('Трябва да избереш типа на поръчката.');
			$('delivery_info').down('fieldset div').insert({ before: errorHtml });
			Effect.ScrollTo('delivery_info', { offset: -100 });
			return false;
		}

		// check if user has selected an order type
		var paymentTypes = $A([$('payment_type_1'), $('payment_type_2')]);
		if(!paymentTypes.any(checked)) {
			cleanPreviousErrors();
			var errorHtml = buildErrorHtml('Трябва да избереш типа на плащането.');
			$('payment_info').down('fieldset div').insert({ before: errorHtml });
			Effect.ScrollTo('payment_info', { offset: -100 });
			return false;
		}
		
		return true;
	}
	
	function cleanPreviousErrors() {
		$$("#order .error").invoke('remove');
	}
	
	function showValidationErrors() {
		$H(PRINTO.Validator.errors()).each(function(pair) {
			var element = pair.key;
			var errors = pair.value;
			if(errors.length == 0) return;
			
			// we only need the first error
			var errorHtml = buildErrorHtml(errors[0]);
			$(element).insert({ after: errorHtml });
		});
	}
	
	function buildErrorHtml(errorText) {
		return '<span class="error">'+errorText+'</span>';
	}	
	
	function calculateShippingCosts() {
		// request shipping costs info
		var params = $H({
			city: getCity(),
			delivery_type: getDeliveryType(),
			sid: window._upload_session_id
		}).toQueryString();
		new Ajax.Request('/welcome/shipping_expenses', { parameters: params });
	}
	
	function toggleInvoiceForm(event) {
		return $F('use_invoice_form') == '1' ? showInvoiceForm() : invoiceForm.hide();
	}
	
	function showInvoiceForm() {
		// pre-fill some of the data
		var invoiceFullName = $('invoice_full_name');
		if(invoiceFullName.value.blank()) {
			invoiceFullName.value = $F('order_first_name') + ' ' + $F('order_last_name');
		}			
		var invoiceAddress = $('invoice_address');
		if(invoiceAddress.value.blank()) {
			invoiceAddress.value = $F('order_address');
		}
		
		invoiceForm.show();
	}
	
	function toggleRecipientForm(event) {
		return $F('use_recipient_form') == '1' ? showRecipientForm() : hideRecipientForm();
	}
	
	function showRecipientForm() {
		// hide the cash on delivery payment option
		hideCodOption();
		recipientForm.show();
	}
	
	function hideRecipientForm() {
		recipientForm.hide();
		showCodOption();
	}
	
	function incrementPoints() {
		if(pointsUsed < totalPoints) {
			updatePointsUsed(pointsUsed+1);
		}
	}	
	
	function decrementPoints() {
		if(pointsUsed > 0) {
			updatePointsUsed(pointsUsed-1);
		}
	}
	
	function updatePointsUsed(points, recalculateOnly) {
		pointsUsed = points;
		if(!recalculateOnly) {
			$('points_to_use').value = points;
		}
	
		PRINTO.OrderManager.recalculatePrice();
	}
	
	function calculateMaxPointsForPrice(price) {
		return Math.floor((discountLimit * price) / pointValue);
	}
		
	return {
		initialize: function() {
			startOrderButton = $('start_order_button');
			startOrderButton.observe('click', startOrder);
		},
		
		setPrices: function(prices) {
			PRICES = prices;
		},
		
		setPricePerSqMeter: function(price) {
			pricePerSqMeter = price;
		},
		
		setCodFee: function(price) {
			codFee = price;
		},
		
		recalculatePrice: function() {
			var price = $H(PRINTO.PHOTOS).inject(0, function(price, pair) { 
				if(pair[1].isUploaded() && !pair[1].isSuspended()) {
					if(pair[1].isPanorama) {
						return price + pricePerSqMeter * pair[1].getArea() * pair[1].copies;
					} else {
						return price + PRICES[ pair[1].getPrintSizeString() ] * pair[1].copies;
					}
				} else {
					return price;
				}
			});
			
			// add shipping costs if available
			if(shippingCosts)
				price += shippingCosts;
			
			if(active && getPaymentType() == 'cod' 
								&& (getDeliveryType() == 'express' || getDeliveryType() == 'superexpress')) {
				price += codFee;
			}
			
			// take into account the discount if the user has chosen to use any of his points
			if(usePoints) {
				var discount = pointsUsed * pointValue;
				
				if(price - discount < ((1 - discountLimit) * price)) {
					var maxPoints = calculateMaxPointsForPrice(price);
					// updatePointsUsed recalculates again
					updatePointsUsed(maxPoints);
					return false;
				} else {
					price -= discount;
				}
			}
			
			totalPrice = price;
			totalPriceVat = price * vatFactor;
			
			var formattedPrice = (Math.round(totalPriceVat * 100)/100).toFixed(2);
			document.fire('printo:pricechanged', formattedPrice);
			
			showStartOrderButton();
			
			// if the total price is above the cash on delivery limit,
			// hide the cash on delivery option
			if(cashOnDeliveryLimit) {
				if(totalPriceVat > cashOnDeliveryLimit) {
					hideCodOption();
					$('payment_type_2').checked = 'checked';
					$('payment_type_2').up().next('p').show();
				} else {
					showCodOption();
				}
			} else {
				if(PRINTO.OrderManager.active())
					showCodOption();
			}
		},
		
		setCashOnDeliveryLimit: function(limit) {
			cashOnDeliveryLimit = limit;
		},
		
		active: function() {
			return active;
		},
		
		setupForm: function(formHtml) {
			startOrderButton.stopObserving();
			startOrderButton.addClassName('disabled');
			$('wrapper').insert({ bottom: formHtml });
			
			(function() { Effect.ScrollTo('order', { offset: -20 }); }).defer();
			attachFormObservers.defer();
		},

		updateShippingCosts: function(value) {
			shippingCosts = parseFloat(value);
			//console.log('shipping costs: ', shippingCosts);
			showShippingCostsContainer();
			shippingCostsContainer.down('span').update(value + ' лв');
			PRINTO.OrderManager.recalculatePrice();
		},
		
		cancelSubmit: function() {
			submitInProgress = false;
		},
		
		fillOrderForm: function(parameters) {
			if($F('order_first_name').blank()) {
				$('order_first_name').value = parameters['first_name'];
			}
		
			if($F('order_last_name').blank()) {
				$('order_last_name').value = parameters['last_name'];
			}
		
			if($F('order_phone').blank()) {
				$('order_phone').value = parameters['phone'];
			}
	
			if($F('order_address').blank()) {
				$('order_address').value = parameters['address'];
			}
		
			if(parameters['city']) {
				var citySelect = $('order_city');
				var cityOptions = citySelect.options;
				for(var i=0; i < cityOptions.length; i++)
				{
					if(cityOptions[i].value == parameters['city']) {
						citySelect.selectedIndex = i;
						break;
					}
				}
			}
		},
		
		setupPointsWidget: function() {
			$('increment_points').observe('click', incrementPoints);
			$('decrement_points').observe('click', decrementPoints);
		
			// FIXME: text input change is being handled in a really weird way
			$('points_to_use').observe('keyup', function(event) {
				setTimeout(function() {
					var points = parseInt($F('points_to_use'), 10);
					// set the second param of updatePointsUsed to true; means that the text field
					// will not get updated and thus focus will not be stolen from the user
				
					if(isNaN(points)) {
						updatePointsUsed(0, true);
					} else {
						updatePointsUsed(points, true);
					}
				}, 100);
			});
		},
				
		disablePoints: function() {
			if($('points_widget')) {
				$('points_widget').remove();
			}
			
			usePoints = false;
			pointsUsed = 0;
			PRINTO.OrderManager.recalculatePrice();
		},
			
		enablePoints: function(newPointValue, newTotalPoints, newDiscountLimit) {
			usePoints = true;
			pointValue = newPointValue;
			totalPoints = newTotalPoints;
			discountLimit = newDiscountLimit;
			PRINTO.OrderManager.setupPointsWidget();
		},
		
		destroy: function() {
			startOrderButton.stopObserving();
			startOrderButton = null;
			
			orderForm = null;
			invoiceForm = null;
			recipientForm = null;
		}
	};	
}();

PRINTO.Taskbar = function() {
	var taskbar;
	var tasksContainer;
	var taskCount = 0;
	var tasks = {};
	var priceContainer;
	var visible = false;
	var taskTemplate = '<span class="progress"></span><span class="number">#{number}</span>';
	var processingTemplate = '<div class="processing_thumbnail"></div><span>Обработване...</span>';
	
	function createTask() {
		taskCount++;
		
		var task = new Element('div', { 'class': 'task' });
		task.update(taskTemplate.interpolate({ number: taskCount }));
		tasksContainer.insert(task);
		
		var tip = new BalloonTip(task, {
			content: '<div class="upload_thumbnail"></div><span>Качване...</span>',
			width: 126,
			height: 120,
			offsetLeft: -18,
			target: taskbar.down('div'),
			positioning: 'relative',
			animatedFade: (PRINTO.isIE6 ? false : true)
		});
		
		return { taskContainer: task, progressContainer: task.down('.progress'), tip: tip, taskNumber: taskCount };
	}
	
	return {
		initialize: function() {
			taskbar = $('taskbar');
			tasksContainer = $('tasks');
			priceContainer = $('taskbar_price').down('strong');
			
			if(PRINTO.isIE6) taskbar.hide();
			Event.observe(window, 'unload', PRINTO.Taskbar.destroy);
			document.observe('printo:pricechanged', function(event) {
				PRINTO.Taskbar.updatePrice(event.memo);
			});
		},
		
		show: function() {
			if(PRINTO.isIE6) {
				taskbar.show();
				//new Effect.Appear(taskbar, { duration: 0.5 });
			} else {
				taskbar.morph('bottom: 0', { duration: 0.5 });
			}
			
			visible = true;
		},
		
		hide: function() {
			if(PRINTO.isIE6) {
				taskbar.hide();
				//new Effect.Fade(taskbar, { duration: 0.5 });
			} else {
				taskbar.morph('bottom: -48px', { duration: 0.5 });
			}
			visible = false;
		},
		
		visible: function() {
			return visible;
		},
		
		addTask: function(photoId) {
			if(!visible) {
				PRINTO.Taskbar.show();
			}
			
			var task = createTask();
			tasks[photoId] = task;
			task.taskContainer.observe('click', function() {
				if($(photoId)) $(photoId).scrollTo();
			});
		},
		
		suspendTask: function(photoId) {
			tasks[photoId].tip.disable();
			tasks[photoId].taskContainer.addClassName('suspended');
			new Effect.Fade(tasks[photoId].taskContainer, { to: 0.5 });
		},
		
		getTaskCount: function() {
			return taskCount;
		},
		
		updateTaskProgress: function(photoId, percentage) {
			tasks[photoId].progressContainer.style.height = percentage+'%';
			if(percentage == 100) {
				tasks[photoId].tip.updateContent(processingTemplate);
				tasks[photoId].progressContainer.addClassName('processing');
			}
		},
		
		updateTaskContent: function(photoId, content) {
			tasks[photoId].tip.updateContent(content);
		},
		
		updatePrice: function(price) {
			priceContainer.update(price);
		},
		
		getTask: function(photoId) {
			return tasks[photoId];
		},
		
		destroy: function() {
			taskbar = null;
			tasksContainer = null;
			priceContainer = null;
			for(task in tasks) {
				task.taskContainer = null;
				task.progressContainer = null;
			}
		}
	};
}();

PRINTO.Photo = Class.create({	
	initialize: function(file, uploadId) {
		this.file = file;
		this.uploadId = uploadId;
		this.uploaded = false;
		this.copies = 1;
		this.suspended = false;
		this.editorInitialized = false;
		this.transformations = {};
		
		this.createUploadTask();
		this.createPhotoBox();
		Event.observe(window, 'unload', this.destroy.bind(this));
	},
	
	createUploadTask: function() {
		PRINTO.Taskbar.addTask(this.uploadId);
	},
	
	createPhotoBox: function() {
		//this.box = $(PRINTO.PHOTO_TEMPLATE.cloneNode(true));
		this.box = new Element('div', { 'class': 'photo', id: this.uploadId });
		this.box.innerHTML = PRINTO.PHOTO_TEMPLATE.innerHTML;
		
		this.box.removeClassName('hide');
		this.box.id = this.uploadId;
		this.number = this.box.down('.number span');
		this.number.update(PRINTO.Taskbar.getTaskCount());
		this.name = this.box.down('.name');
		this.tabs = this.box.down('.tabs');
		this.deleteButton = this.tabs.down('.delete');
		this.thumbnailContainer = this.box.down('.thumbnail');
		this.thumbnail = this.thumbnailContainer.down('img');
		this.thumbnailFrameTop = this.thumbnailContainer.down('.frame_top');
		this.thumbnailFrameBottom = this.thumbnailContainer.down('.frame_bottom');
		this.thumbnailFrameLeft = this.thumbnailContainer.down('.frame_left');
		this.thumbnailFrameRight = this.thumbnailContainer.down('.frame_right');

		this.thumbnailFrameTopLeft = this.thumbnailContainer.down('.frame_topleft');
		this.thumbnailFrameTopRight = this.thumbnailContainer.down('.frame_topright');

		this.thumbnailFrameBottomLeft = this.thumbnailContainer.down('.frame_bottomleft');
		this.thumbnailFrameBottomRight = this.thumbnailContainer.down('.frame_bottomright');
		
		this.sizeInputs = this.box.select('.sizes_radios input');
		this.copiesInputs = this.box.select('.copies_radios input');
		
		this.sizeInputs.invoke('writeAttribute', 'name', this.uploadId+'size');
		this.copiesInputs.invoke('writeAttribute', 'name', this.uploadId+'copies');

		this.editorContainer = this.box.down('.editor_container');
		
		/* Tabs */
		this.tabLinks = this.tabs.select('li a');
		this.tabPanes = this.box.select('.tab_content');
		this.tabMap = {};
		this.tabLinks.each(function(link) {
			var paneName = link.href.replace(/.*#/, '');
			var pane = this.tabPanes.detect(function(p) { return p.hasClassName(paneName); });
			this.tabMap[paneName] = { link: link, pane: pane };
			link.observe('click', this.selectTab.bindAsEventListener(this, paneName));
		}, this);
		
		/* Observers */
		this.box.down('.copies_radios').observe('click', this.onNumCopiesClick.bind(this));
		this.box.down('.sizes_radios').observe('click', this.onSizesClick.bind(this));
		this.box.down('.num_copies_other').observe('keyup', this.onOtherNumCopiesChange.bind(this));		
		this.box.down('.tabs .delete').observe('click', this.remove.bind(this));
		this.box.down('.editor .pane .help').observe('click', function(event) {
			$(this).up().next('div').toggle();
		});
	},

	getPrintSizeIndex: function() {
  	if(this.isPanorama)
  		return this.getPrintSizeString();
  	
		var min = [this.printWidth, this.printHeight].min();
		var max = [this.printWidth, this.printHeight].max();
		
		for(var i=0; i < PRINTO.PRINT_SIZES.length; i++) {
			var size = PRINTO.PRINT_SIZES[i];
			if(size[0] == max && size[1] == min)
				return i;
		}
		return -1;
  },
	
	remove: function(event) {
		Event.stop(event);
		
		if(confirm('Сигурен ли си, че искаш да изтриеш снимката?')) {		
			if(this.editor) {
				this.editor.remove();
			}
			this.box.style.overflow = 'hidden';
			this.box.morph({ marginBottom: '0px', height: '0px' });
			this.suspended = true;
			PRINTO.Taskbar.suspendTask(this.uploadId);
			PRINTO.OrderManager.recalculatePrice();
			new Ajax.Request('/files/delete/'+this.uploadId, { method: 'post', parameters: 'sid='+window._upload_session_id });
		}		
	},
	
	onOtherNumCopiesChange: function(event) {
		// TODO: do a quick format check
		this.setNumCopies(parseInt(this.currentCopiesInput.value, 10) || 0);
	},
	
	onNumCopiesClick: function(event) {
		var clickedElement = Event.element(event);
		
		if(clickedElement.tagName.toLowerCase() === 'div' && clickedElement.hasClassName('other')) {
			if(this.currentCopiesInput) this.currentCopiesInput.up().removeClassName('selected');
			
			this.currentCopiesInput = clickedElement.down('.text');
			clickedElement.down('input').checked = true;
			clickedElement.addClassName('selected');
			this.currentCopiesInput.focus();
			this.setNumCopies(this.currentCopiesInput.value);
		}
		
		if(clickedElement.tagName.toLowerCase() === 'input' || (PRINTO.isIE6 && clickedElement.tagName.toLowerCase() === 'label')) {
			if(PRINTO.isIE6 && clickedElement.tagName.toLowerCase() === 'label') { 
				var clickedElement = clickedElement.down('input');
				clickedElement.checked = true;
			}
			
			if(this.currentCopiesInput) this.currentCopiesInput.up().removeClassName('selected');
			clickedElement.up().addClassName('selected');
			
			if(clickedElement.value == '-1' || clickedElement.type == 'text') {
				// "Other" option clicked
				if(clickedElement.type == 'radio') {
					// radio button clicked
					this.currentCopiesInput = clickedElement.next('input');
				} else {
					// text field clicked
					this.currentCopiesInput = clickedElement;
					clickedElement.previous('input').checked = true;
				}
			} else {
				this.currentCopiesInput = clickedElement;
			}
			this.setNumCopies(this.currentCopiesInput.value);
		}
	},

	onSizesClick: function(event) {
		var clickedElement = Event.element(event);
		if(clickedElement.tagName.toLowerCase() === 'input' || (PRINTO.isIE6 && clickedElement.tagName.toLowerCase() === 'label')) {
			if(PRINTO.isIE6 && clickedElement.tagName.toLowerCase() === 'label') { 
				var clickedElement = clickedElement.down('input');
				clickedElement.checked = true;
			}
			if(this.currentSizeInput) this.currentSizeInput.up().removeClassName('selected');
			clickedElement.up().addClassName('selected');
			this.currentSizeInput = clickedElement;
			var newSize = this.currentSizeInput.value.split('x').map(function(n) { return parseInt(n, 10); });
			this.setPrintSize(newSize);
			this.updateThumbnailFrame(newSize);
			this.updateTaskPreview();
		}
	},
	
	selectTab: function(event, pane) {
		Event.stop(event);
		
		this.tabLinks.invoke('removeClassName', 'selected');
		this.tabPanes.invoke('addClassName', 'hide');
		this.tabMap[pane].link.addClassName('selected');
		this.tabMap[pane].pane.removeClassName('hide');
		
		if(pane == 'editor') {
			if(this.editorInitialized) {
				this.loadIntoEditor();
			} else {
				this.initializeEditor();
			}
		} else if (pane == 'size_copies') {
			// make sure the editor saves all data
			this.saveTransformations(this.editor.getTransformations());
		}
	},
	
	initializeEditor: function() {
		var flashVars = {};
		var params = {
			allowScriptAccess: 'always',
			wmode: 'opaque'
		};
		
		var editorId = this.editorContainer.identify();
		swfobject.embedSWF('/ImageEditor.swf', editorId, '566', '400', '9.0.0', '/expressInstall.swf', flashVars, params);
		this.editorInitialized = true;
		this.editor = $(editorId);
		
		this.loadIntoEditor();
	},
	
	loadIntoEditor: function() {
    this.editorLoadImageInterval = setInterval(function() {
    	if(typeof this.editor.loadImage == 'function') {
  			this.editor.loadImage(this.uploadId, this.editablePhotoUrl, [this.printWidth, this.printHeight], this.transformations || {});
  			clearInterval(this.editorLoadImageInterval);
  		}
  	}.bind(this), 100);
	},
	
	setUploadStatus: function(bytesLoaded, bytesTotal) {
		var percentage = Math.round(bytesLoaded/bytesTotal*100) || 5;
		PRINTO.Taskbar.updateTaskProgress(this.uploadId, percentage);
	},
			
	finishUpload: function(data) {
    this.uploaded = true;
		
    this.editablePhotoUrl = data.editablePhotoUrl;
    this.isPanorama = data.isPanorama;
    if(this.isPanorama) {
    	this.panoramaSizes = data.panoramaSizes;
    	
    	// replace the sizes that we currently have with the panoramic ones
    	this.replaceSizes(this.panoramaSizes);
    }
		
		this.setUploadStatus(1, 1);
		
    this.printWidth = data.printSize[0];
    this.printHeight = data.printSize[1];
    this.width = data.actualSize[0];
    this.height = data.actualSize[1];
		
		this.name.update(data.name);
		this.updateThumbnail(data.thumb.src, data.thumb.width, data.thumb.height, data.name);
		
		var photosContainer = PRINTO.PhotoManager.photosContainer;
		photosContainer.removeClassName('hide');
		photosContainer.insert(this.box);

		// IE cannot set the name attribute dynamically without an ugly hack, so here goes
		if(PRINTO.isIE6) {
			this.copiesInputs.each(function(input) {
				input.outerHTML = input.outerHTML.replace(/photo\[copies\]/, '"'+this.uploadId+'copies"');
			}, this);
			
			this.sizeInputs.each(function(input) {
				input.outerHTML = input.outerHTML.replace(/photo\[size\]/, '"'+this.uploadId+'size"');
			}, this);
		}
		
		this.sizeInputs = this.box.select('.sizes_radios input');
		this.copiesInputs = this.box.select('.copies_radios input');
		
    this.currentSizeInput = this.sizeInputs.detect(function(input) {
    	return input.value == this.getPrintSizeString();
    }, this);
    
    if(this.currentSizeInput) {
	    (function() { this.currentSizeInput.checked = true; }).bind(this).defer();
	    this.currentSizeInput.up().addClassName('selected');
    }

    this.currentCopiesInput = this.copiesInputs.detect(function(input) {
    	return input.value == '1';
    }, this);
    
    if(this.currentCopiesInput) {
    	(function() { this.currentCopiesInput.checked = true; }).bind(this).defer();
    }
		
		this.updateThumbnailFrame(this.getPrintSize());
		
		this.updateTaskPreview();
		PRINTO.OrderManager.recalculatePrice();
		if(PRINTO.Taskbar.getTask(this.uploadId).taskNumber == 1) {
			this.scrollTo.bind(this).defer();
		}
	},
	
	scrollTo: function() {
		Effect.ScrollTo(this.uploadId, { offset: -100 });
	},
	
	replaceSizes: function(newSizes) {
		var container = this.box.down('.sizes_radios');
		var chunks = newSizes.sortBy(function(s) { return s[0]*s[1]; }).inGroupsOf(4);
		var uploadId = this.uploadId;
		
		var htmlChunks = [];
		chunks.each(function(sizes, columnIndex) {
			var columnHtml = '<div class="column base_size'+(columnIndex+1)+'">';
			sizes.compact().each(function(size, sizeIndex) {
				columnHtml += '<label class="label size#{sizeIndex}"><input type="radio" name="photo[#{photoId}][size]" value="#{sizeString}" /> #{sizeString}</label>'.interpolate({ sizeIndex: sizeIndex+1, photoId: uploadId, sizeString:  size.sort().join('x') });
			});
			columnHtml += '</div>';
			htmlChunks.push(columnHtml);
		});
		
		container.update(htmlChunks.join(''));
		this.sizeInputs = container.select('input');
	},
	
	updateThumbnail: function(src, width, height, alt) {
		this.thumbnail.src = src;
		if(alt) this.thumbnail.alt = alt;
		this.thumbnail.width = width;
		this.thumbnail.height = height;
		
		this.thumbnail.setStyle({ marginTop: (-height/2)+'px', marginLeft: (-width/2)+'px' });
	},
	
	isLandscape: function() {
		if(this.transformations.o) {
			return this.transformations.o == 'landscape';
		} else {
			return this.width > this.height;
		}
	},
	
	isPortrait: function() {
		return !this.isLandscape();
	},
	
	updateThumbnailFrame: function(frameSize) {
		var photoAspectRatio = this.hasBeenEdited ? this.thumbnail.width / this.thumbnail.height : this.width / this.height;
		
		if(this.isLandscape()) {
			// landscape case
			var frameAspectRatio = frameSize.max() / frameSize.min();
		} else {
			// portrait case
			var frameAspectRatio = frameSize.min() / frameSize.max();
		}
		
		if(frameAspectRatio < photoAspectRatio) {
			var frameHeight = this.thumbnail.height;
			var frameWidth = frameAspectRatio * frameHeight;
		} else {
			var frameWidth = this.thumbnail.width;
			var frameHeight = frameWidth*(1/frameAspectRatio);
		}
		
		var frameSideWidth = (PRINTO.Photo.thumbnailContainerWidth-frameWidth)/2;
		var frameCapHeight = (PRINTO.Photo.thumbnailContainerHeight-frameHeight)/2;
		
		this.thumbnailFrameLeft.morph('width: '+frameSideWidth+'px', { duration: 0.5 });
		this.thumbnailFrameRight.morph('width: '+frameSideWidth+'px', { duration: 0.5 });
		this.thumbnailFrameTop.morph('height: '+frameCapHeight+'px', { duration: 0.5 });
		this.thumbnailFrameBottom.morph('height: '+frameCapHeight+'px', { duration: 0.5 });
		this.thumbnailFrameTopLeft.morph('left: '+(frameSideWidth-20)+'px; height: '+frameCapHeight+'px; width: '+((frameWidth+42)/2)+'px', { duration: 0.5 });
		this.thumbnailFrameTopRight.morph('right: '+(frameSideWidth-20)+'px; height: '+frameCapHeight+'px; width: '+((frameWidth+42)/2)+'px', { duration: 0.5 });
		this.thumbnailFrameBottomLeft.morph('left: '+(frameSideWidth-20)+'px; height: '+frameCapHeight+'px; width: '+((frameWidth+42)/2)+'px', { duration: 0.5 });
		this.thumbnailFrameBottomRight.morph('right: '+(frameSideWidth-20)+'px; height: '+frameCapHeight+'px; width: '+((frameWidth+42)/2)+'px', { duration: 0.5 });
	},

	updateTaskPreview: function() {
		var template = '<div class="thumbnail"><a href="##{uploadId}"><img src="#{taskThumbnail}" /></a></div><div class="info"><span class="copies">#{copies}</span> x <span class="size">#{size}</span></div>';
		
		PRINTO.Taskbar.updateTaskContent(this.uploadId, template.interpolate({
			uploadId: this.uploadId,
			taskThumbnail: this.thumbnail.src.replace(/thumb/, 'task'),
			copies: this.copies,
			size: this.getPrintSizeString()
		}));
		
		PRINTO.Taskbar.getTask(this.uploadId).progressContainer.removeClassName('processing');
	},

  saveTransformations: function(transformations)
  {
    this.transformations = transformations;
    //console.log(this.transformations);
    // update the preview accordingly
    var params = $H({
        id: this.uploadId, 
        x: this.transformations.x,
        y: this.transformations.y,
        s: this.transformations.s,
        r: this.transformations.r,
        o: this.transformations.o,
        bw: this.transformations.bw,
        sepia: this.transformations.sepia,
        sid: window._upload_session_id
    }).toQueryString();
    
    new Ajax.Request('/files/update', { method: 'post', parameters: params, onLoading: this.showSaveLoadingMessage.bind(this), onComplete: this.showSaveCompleteMessage.bind(this) });
    this.hasBeenEdited = true;
  },
  
  showSaveLoadingMessage: function() {
  	var editorMessage = this.createEditorMessage();
		editorMessage.innerHTML = 'Запазване на промените...';
		editorMessage.removeClassName('success');
  	editorMessage.addClassName('loading');
  	editorMessage.show();
  },
  
  showSaveCompleteMessage: function() {
  	var editorMessage = this.createEditorMessage();
		editorMessage.innerHTML = 'Промените бяха запазени успешно!';
  	editorMessage.removeClassName('loading');
		editorMessage.addClassName('success');
  	editorMessage.show();
  },
  
  createEditorMessage: function() {
  	if(!this.editorMessage) {
  		this.editorMessage = new Element('div', { 'class': 'editor_message' });
  		this.editorMessage.hide();
			this.box.down('.editor .pane').insert({ top: this.editorMessage });
  	}
  	
  	return this.editorMessage;
  },
  
  reloadThumbnail: function(thumbWidth, thumbHeight) {
    this.updateThumbnail(this.thumbnail.src + '?' + Math.random(), thumbWidth, thumbHeight);
    this.updateThumbnailFrame(this.getPrintSize());
  },  
	
  getDimensions: function() {
  	return [this.width, this.height];
  },
  
  setPrintSize: function(size) {
    if(this.width > this.height) {
      this.printWidth = size.max();
      this.printHeight = size.min();
    } else {
      this.printWidth = size.min();
      this.printHeight = size.max();
    }

    // if the user is already at the ordering phase and has decided to
    // change the size of a photo, the change should be reflected on
    // the server side
    if(PRINTO.OrderManager.active()) {
    	new Ajax.Request('/files/update_size/'+this.uploadId, { method: 'post', 
    		parameters: 'print_size='+[size[1], size[0]].join('x')+'&sid='+window._upload_session_id
  		});
    }
    
    PRINTO.OrderManager.recalculatePrice();
  },
  
  getPrintSize: function() {
    return [this.printWidth, this.printHeight];
  },
  
  getArea: function() {
  	return (this.printWidth * this.printHeight)/10000;
  },
  
	getPrintSizeString: function() {
		var printSize = this.getPrintSize();
		return [printSize.min(), printSize.max()].join('x');
	},

  getIdealPrintSize: function() {
    var ppi = 254;
    
    var width_cm = this.width/ppi * 2.54;
    var height_cm = this.height/ppi * 2.54;
    
    var area = width_cm * height_cm;
    var ideal_size = PRINTO.PRINT_SIZES.detect(function(size) { return area < (size[0] * size[1]); }) || false;
    if(!ideal_size)
      return false;
        
    if(width_cm < height_cm)
      return [ideal_size.min(), ideal_size.max()];
    else
      return [ideal_size.max(), ideal_size.min()];
  },
  
	setNumCopies: function(numCopies) {
		this.copies = numCopies;
		
		PRINTO.OrderManager.recalculatePrice();
		this.updateTaskPreview();
		
		if(PRINTO.OrderManager.active()) {
    	new Ajax.Request('/files/update_copies/'+this.uploadId, { method: 'post', 
    		parameters: 'copies='+numCopies+'&sid='+window._upload_session_id
  		});
		}
	},
	
	isUploaded: function() {
		return this.uploaded;
	},
	
	isSuspended: function() {
		return this.suspended;
	},
	
	destroy: function() {
		this.box = null;
		this.number = null;
		this.tabs = null;
		this.deleteButton = null;
		this.thumbnail = null;
		this.thumbnailContainer = null;
		
		this.thumbnailFrameTop = null;
		this.thumbnailFrameBottom = null;
		this.thumbnailFrameLeft = null;
		this.thumbnailFrameRight = null;
		
		for(i = 0, l = this.tabLinks.length; i < l; i++) {
			this.tabLinks[i] = null;
		}
		
		for(i = 0, l = this.tabPanes.length; i < l; i++) {
			this.tabPanes[i] = null;
		}
		
		for(pair in this.tabMap) {
			pair.link = null;
			pair.pane = null;
		}
	}
});
PRINTO.Photo.thumbnailContainerWidth = 440;
PRINTO.Photo.thumbnailContainerHeight = 350;
		
PRINTO.PHOTOS = {};
PRINTO.PRINT_SIZES = [
  [18, 13], [21, 15], [24, 18], [25, 20], 
  [30, 20], [30, 24], [40, 30], [45, 30], 
  [50, 40], [60, 40], [70, 50], [100, 70], 
  [200, 70]
];

PRINTO.Validator = function() {
	var defaultErrorStrings = {
		'name': 'Невалидно име',
		'phone': 'Невалиден телефонен номер',
		'notempty': 'Полето не може да бъде празно',
		'email': 'Невалиден e-mail адрес'
	};
	
	var errors = {};
	var validationTests = {
		testName: function(value) {
			if(/\u430/.test('а')) {
				// for browsers that support unicode ranges in regular expressions
				return value.match(/^[a-z\u0400-\u052F\-]+$/i) ? true : false;
			}	else {
				// and for those that don't
				return value.match(/[0-9!@#$%^&*()_+}{|';:"><.,\/~`=-]/) ? false : true;
			}
		},
		
		testPhone: function(value) {
			return value.match(/^[0-9\s\/\.+-]+$/) ? true : false;
		},
		
		testNotempty: function(value) {
			return !value.blank();
		},
		
		testEmail: function(value) {
			return value.match(/^([^@\s]+)@((?:[-a-z0-9]+.)+[a-z]{2,})$/i) ? true : false;
		}
	};
	
	return {
		validate: function(validationMap) {
			var valid = true;
			errors = {};
			
			$H(validationMap).each(function(pair) {
				var elementName = pair.key;
				if(!$(elementName))
					return true;
					
				var elementValue = $F(elementName);
				
				if(elementValue === false) return;
				errors[elementName] = [];
				
				var validators = pair.value.split('|');
				
				for(var i=0; validator = validators[i]; i++) {
					// figure out the validator name and the corresponding error string
					if(validator.indexOf(':') != -1) {
						var matches = validator.match(/(\w+):(.*)/);
						var validatorName = 'test'+matches[1].capitalize();
						var errorString = matches[2];
					} else {
						var validatorName = 'test'+validator.capitalize();
						var errorString = defaultErrorStrings[validator];
					}
					
					// validate field if validator exists
					if(validationTests[validatorName]) {
						if(!validationTests[validatorName](elementValue)) {
							errors[elementName].push(errorString);
							valid = false;
						}
					}	
				}
			});
			
			return valid;
		},
		
		errorsOn: function(field) {
			return errors[field];
		},
		
		errors: function() {
			return errors;
		}
	};
}();

PRINTO.showAuthenticationError = function() {
	alert('Грешни потребителско име и/или парола!');
};

PRINTO.isIE6 = false /*@cc_on || @_jscript_version < 5.7 @*/;

function randomString(l) {
	var l = l || 8;
	var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
	var randomstring = '';
	for (var i=0; i<l; i++) {
		var rnum = Math.floor(Math.random() * chars.length);
		randomstring += chars.substring(rnum,rnum+1);
	}
	return randomstring;
}

window._upload_session_id = randomString();

document.observe('dom:loaded', function() {
	PRINTO.App.initialize();
});
