$(document).ready(function () {
	$('.setLang').click(function (e) {
		$.get(this.href, function () {window.location.reload();});
		e.preventDefault();
	});
	if (location.hash == "#paymentCancel") {
		SexyLightbox.initialize({color:"white", imagesdir: rootDir + "/images"});
		setTimeout(showPaymentCancel, 100);
		location.hash = "";
	}
});
function showPaymentCancel() {
	SexyLightbox.show('', rootDir + '/' + i18n.paymentCancelHtml + '?width=300&height=120', '');
}
function parseFinnishFloat (string) {
	var replaced = string.replace(",", ".");
	return parseFloat(replaced);
}
var CheckoutDialog = $.klass({
	initialize: function(options) {
		this.options = {
			cartUrl: rootUrl + 'loginOrder.php',
			location: absoluteRoot + 'muokkaaTilaus/' + cart.share_url,
			confirmUrl: rootUrl + 'confirmOrder.php',
			cancelUrl: rootUrl + 'cancelOrder.php',
			billPayment: rootUrl + 'billPayment.php'
		}
		$.extend(this.options, options);
		this.loadHtml();
		return this;
	},
	initHtml: function(data) {
		
		this.element.html(data);
		//this.element.find('#company').focus();
		this.element.find('.itemCount').bind('keyup change', $.proxy(this.countChanged, this));
		this.element.find('#terms').bind('change', $.proxy(this.termsOkChanged, this));
		this.termsOkChanged();
	},
	loadHtml: function () {
		this.element = $('<div class="checkout"/>');
		this.element.html('<img src="' + rootUrl + 'images/loading.gif" />');
		this.element.dialog({
			width: 755,
			height: 700,
			modal: true,
			buttons: [
				{
					text: i18n.feedbackCancel,
					click: $.proxy(this.close, this)
				},
				{
					text: i18n.checkoutSummaryPayment,
					click: $.proxy(this.toConfirm, this),
					disabled: true
				}
			],
			title: i18n.checkoutConfirmOrder
		});
		this.element.bind("dialogclose", function () {window.location.reload();})
		$.get(
			this.options.cartUrl,
			{offer: cart.id},
			$.proxy(this.initHtml, this)
		);
	},
	cancel: function () {
		$.get(
			this.options.cancelUrl,
			{offer: cart.id},
			function () {window.location.reload();}
		);
	},
	chooseMethod1: function () {
		this.element.find('input[name=paymentMethod][value=1]').click();
		this.paymentMethodChange();
	},
	chooseMethod2: function () {
		this.element.find('input[name=paymentMethod][value=2]').click();
		this.paymentMethodChange();
	},
	close: function (data) {
		this.element.dialog('close');
	},
	confirm: function () {
		this.element.find('#send').click();
	},
	confirmBill: function () {
		this.element.dialog( 'option', 'buttons', [
			{
				text: i18n.feedbackCancel,
				click: $.proxy(this.close, this)
			}
		]);
		$.post(
			this.options.billPayment,
			{
				offer: cart.id
			},
			$.proxy(this.confirmBillCallback, this),
			'json'
		)
	},
	confirmBillCallback: function(data) {
		if (data.valid) {
			window.location = data.redirect;
		}
		else {
			if (this.element.find('.billOk').length > 0) {
				this.element.dialog( 'option', 'buttons', [
					{
						text: i18n.feedbackCancel,
						click: $.proxy(this.close, this)
					},
					{
						text: i18n.checkoutBillPayment,
						click: $.proxy(this.confirmBill, this)
					}
				]);
				
			}
			else {
				this.element.dialog( 'option', 'buttons', [
					{
						text: i18n.feedbackCancel,
						click: $.proxy(this.close, this)
					},
					{
						text: i18n.checkoutEbankPayment,
						click: $.proxy(this.confirm, this)
					}
				]);
			}
		}
	},
	confirmCallback: function (data) {
		this.element.html(data);
		if (this.element.find('.billOk').length > 0) {
			this.element.dialog( 'option', 'buttons', [
				{
					text: i18n.feedbackCancel,
					click: $.proxy(this.close, this)
				},
				{
					text: i18n.checkoutBillPayment,
					click: $.proxy(this.confirmBill, this)
				}
			]);
			
		}
		else {
			this.element.dialog( 'option', 'buttons', [
				{
					text: i18n.feedbackCancel,
					click: $.proxy(this.close, this)
				},
				{
					text: i18n.checkoutEbankPayment,
					click: $.proxy(this.confirm, this)
				}
			]);
		}
		this.element.find('input[name=paymentMethod]').change($.proxy(this.paymentMethodChange, this));
		this.element.find('.paymentMethod1').click($.proxy(this.chooseMethod1, this));
		this.element.find('.paymentMethod2').click($.proxy(this.chooseMethod2, this));
		// poistetaan alkuperäinen reload bindaus
		this.element.unbind("dialogclose");
		this.element.bind( "dialogclose", $.proxy(this.cancel, this));
	},
	countChanged: function () {
		if (this.priceUpdate != null) {
			clearTimeout(this.priceUpdateTimer);
		}
		this.priceUpdateTimer = setTimeout($.proxy(this.priceUpdate, this), 750);
	},
	paymentMethodChange: function () {
		// jos valittu käytettäväksi lasku
		if (this.element.find('input[name=paymentMethod]:checked').val() == 2) {
			var data = [];
			data.push({name: 'offer', value: cart.id});
			data.push({name: 'paymentMethod', value: '2'});
			$.get(
				this.options.confirmUrl,
				data,
				$.proxy(this.confirmCallback, this)
			);
			this.element.dialog( 'option', 'buttons', [
				{
					text: i18n.feedbackCancel,
					click: $.proxy(this.close, this)
				}
			]);
			this.element.html('<img src="' + rootUrl + 'images/loading.gif" />');
		}
		else {
			var data = [];
			data.push({name: 'offer', value: cart.id});
			data.push({name: 'paymentMethod', value: '1'});
			$.get(
				this.options.confirmUrl,
				data,
				$.proxy(this.confirmCallback, this)
			);
			this.element.dialog( 'option', 'buttons', [
				{
					text: i18n.feedbackCancel,
					click: $.proxy(this.close, this)
				}
			]);
			this.element.html('<img src="' + rootUrl + 'images/loading.gif" />');
		}
	},
	priceUpdate: function () {
		var params = this.element.find('.itemCount').serializeArray();
		params.push({name: 'changeCounts', value: true});
		params.push({name: 'offer', value: cart.id});
		$.get(
			this.options.cartUrl,
			params,
			$.proxy(this.initHtml, this)
		);
	},
	termsOkChanged: function() {
		var disabled = true;
		if (this.element.find('#terms:checked').size() > 0) {
			disabled = false;
		}
		
		this.element.dialog( 'option', 'buttons', [
			{
				text: i18n.feedbackCancel,
				click: $.proxy(this.close, this)
			},
			{
				text: i18n.checkoutSummaryPayment,
				click: $.proxy(this.toConfirm, this),
				disabled: disabled
			}
		]);
	},
	toConfirm: function () {
		// jos pending päivitys, estetään se
		if (this.priceUpdate != null) {
			clearTimeout(this.priceUpdateTimer);
		}
		var valid = true;
		var reqs = ['email', 'first_name', 'last_name', 'address', 'city', 'zip'];
		for (i in reqs) {
			var input = $('#' + reqs[i]);
			if (input.val() == '') {
				input.parent().parent().addClass('ui-state-error');
				valid = false;
			}
		}
		if (!valid) {
			$('<div><p>' + i18n.checkoutFillIn + '</p></div>').dialog({
				modal: true,
				title: i18n.checkoutError,
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
					}
				}
			});
		}
		else {
			var data = this.element.find('form').serializeArray();
			data.push({name: 'offer', value: cart.id});
			data.push({name: 'paymentMethod', value: '1'});
			$.get(
				this.options.confirmUrl,
				data,
				$.proxy(this.confirmCallback, this)
			);
			this.element.dialog( 'option', 'buttons', [
				{
					text: i18n.feedbackCancel,
					click: $.proxy(this.close, this)
				}
			]);
			this.element.html('<img src="' + rootUrl + 'images/loading.gif" />');
		}
	}
});
var Cropper = $.klass({
	initialize: function(item, options) {
		this.options = {
			maxSize: 400
		}
		this.item = item;
		$.extend(this.options, options);
		
		
		this.dragObject = false;
		this.hideDraggersTimer = null;
		
		
		this.marginX = this.item.varArray.stans.margin_x / this.item.varArray.stans.width / 2;
		this.marginY = this.item.varArray.stans.margin_y / this.item.varArray.stans.height / 2;
		this.paperW = this.options.maxSize;
		this.paperH = this.options.maxSize;
		
		if (this.item.varArray.orig_width > this.item.varArray.orig_height) {
			this.paperH = Math.round(this.item.varArray.orig_height / this.item.varArray.orig_width * this.options.maxSize);
		}
		else {
			this.paperW = Math.round(this.item.varArray.orig_width / this.item.varArray.orig_height * this.options.maxSize);
		}
		
		this.cropPxX = this.item.varArray.crop_start_x / this.item.varArray.orig_width * this.paperW;
		this.cropPxY = this.item.varArray.crop_start_y / this.item.varArray.orig_height * this.paperH;
		this.cropPxW = this.item.varArray.crop_width / this.item.varArray.orig_width * this.paperW;
		this.cropPxH = this.item.varArray.crop_height / this.item.varArray.orig_height * this.paperH;
		
		this.cornerData = [
			{
				x: this.cropPxX,
				y: this.cropPxY,
				cursor: 'nw-resize',
				drag: this.dragStartNW
			}, 
			{
				x: this.cropPxX + this.cropPxW,
				y: this.cropPxY,
				cursor: 'ne-resize',
				drag: this.dragStartNE
			}, 
			{
				x: this.cropPxX,
				y: this.cropPxY + this.cropPxH,
				cursor: 'sw-resize',
				drag: this.dragStartSW
			}, 
			{
				x: this.cropPxX + this.cropPxW,
				y: this.cropPxY + this.cropPxH,
				cursor: 'se-resize',
				drag: this.dragStartSE
			}
		];
		this.xMultipliers = [-1,  1, -1, 1];
		this.yMultipliers = [-1, -1,  1, 1];
		
		this.initHtml();
		
		$(document).mousemove($.proxy(this.mousemove, this));
		$(document).mouseup($.proxy(this.mouseup, this));
		
		return this;
	},
	centerX: function (e) {
		e.preventDefault();
		this.setX((this.paperW - this.getWidth()) / 2);
	},
	centerY: function (e) {
		e.preventDefault();
		this.setY((this.paperH - this.getHeight()) / 2);
	},
	draggersHide: function(e, f) {
		if (!this.dragObject) {
			for ( var i = 0; i < 4; i++) {
				this.corners[i].animate( {
					"stroke-opacity" : 0,
					"fill-opacity" : 0
				}, 300);
			}
		}
	},
	draggersShow: function() {
		if (this.hideDraggersTimer != null) {
			clearTimeout(this.hideDraggersTimer);
		}
		for ( var i = 0; i < 4; i++) {
			// stop current animation
			this.corners[i].stop();
			this.corners[i].animate( {
				"stroke-opacity" : 1,
				"fill-opacity" : 1
			}, 50);
		}
	},
	draggingCornerMove: function (x, y) {
		if (this.draggingCorner == 0) {
			if ((this.rectangle.attr("x") + x > this.xmargin(this.rectangle.attr("width") + x) || x >= 0) 
					&& (this.rectangle.attr("y") + y > this.ymargin(this.rectangle.attr("height") + y) || y >= 0)) {
				this.rectangle.attr("x", this.rectangle.attr("x") + x);
				this.rectangle.attr("width", this.rectangle.attr("width") - x);
				this.rectangle.attr("y", this.rectangle.attr("y") + y);
				this.rectangle.attr("height", this.rectangle.attr("height") - y);
				if (this.square) {
					
				}
				else {
					this.circle.attr("cx", this.circle.attr("cx") + x/2);
					this.circle.attr("rx", this.circle.attr("rx") - x/2);
					this.circle.attr("cy", this.circle.attr("cy") + y/2);
					this.circle.attr("ry", this.circle.attr("ry") - y/2);
					
					this.dashCircle.attr("cx", this.dashCircle.attr("cx") + x/2);
					this.dashCircle.attr("rx", this.dashCircle.attr("rx") - x/2);
					this.dashCircle.attr("cy", this.dashCircle.attr("cy") + y/2);
					this.dashCircle.attr("ry", this.dashCircle.attr("ry") - y/2);
				}
				this.corners[1].translate(0, y);
				this.corners[2].translate(x, 0);
				
				this.corners[this.draggingCorner].translate(x, y);
				this.inspectMargins();
			}
		}
		else if (this.draggingCorner == 1) {
			if ((this.rectangle.attr("x") + this.rectangle.attr("width") + x < this.paperW - this.xmargin(this.rectangle.attr("width") + x) || x <= 0)
					&& (this.rectangle.attr("y") + y > this.ymargin(this.rectangle.attr("height") + y) || y >= 0)) {
				this.rectangle.attr("width", this.rectangle.attr("width") + x);
				this.rectangle.attr("y", this.rectangle.attr("y") + y);
				this.rectangle.attr("height", this.rectangle.attr("height") - y);
				if (this.square) {
					
				}
				else {
					this.circle.attr("cx", this.circle.attr("cx") + x/2);
					this.circle.attr("rx", this.circle.attr("rx") + x/2);
					this.circle.attr("cy", this.circle.attr("cy") + y/2);
					this.circle.attr("ry", this.circle.attr("ry") - y/2);
					this.dashCircle.attr("cx", this.dashCircle.attr("cx") + x/2);
					this.dashCircle.attr("rx", this.dashCircle.attr("rx") + x/2);
					this.dashCircle.attr("cy", this.dashCircle.attr("cy") + y/2);
					this.dashCircle.attr("ry", this.dashCircle.attr("ry") - y/2);
					
				}
				this.corners[0].translate(0, y);
				this.corners[3].translate(x, 0);
				
				this.corners[this.draggingCorner].translate(x, y);
				this.inspectMargins();
			}
		}
		else if (this.draggingCorner == 2) {
			if ((this.rectangle.attr("x") + x > this.xmargin(this.rectangle.attr("width") + x) || x >= 0) 
					&& (this.rectangle.attr("y") + this.rectangle.attr("height") + y < this.paperH - this.ymargin(this.rectangle.attr("height") + y) || y <= 0)) {
				this.rectangle.attr("x", this.rectangle.attr("x") + x);
				this.rectangle.attr("width", this.rectangle.attr("width") - x);
				this.rectangle.attr("height", this.rectangle.attr("height") + y);
				if (this.square) {
					
				}
				else {
					this.circle.attr("cx", this.circle.attr("cx") + x/2);
					this.circle.attr("rx", this.circle.attr("rx") - x/2);
					this.circle.attr("cy", this.circle.attr("cy") + y/2);
					this.circle.attr("ry", this.circle.attr("ry") + y/2);
					
					this.dashCircle.attr("cx", this.dashCircle.attr("cx") + x/2);
					this.dashCircle.attr("rx", this.dashCircle.attr("rx") - x/2);
					this.dashCircle.attr("cy", this.dashCircle.attr("cy") + y/2);
					this.dashCircle.attr("ry", this.dashCircle.attr("ry") + y/2);
					
				}
				this.corners[0].translate(x, 0);
				this.corners[3].translate(0, y);
				
				this.corners[this.draggingCorner].translate(x, y);
				this.inspectMargins();
			}
		}
		else if (this.draggingCorner == 3) {
			if ((this.rectangle.attr("x") + this.rectangle.attr("width") + x < this.paperW - this.xmargin(this.rectangle.attr("width") + x) || x <= 0)
					&& (this.rectangle.attr("y") + this.rectangle.attr("height") + y < this.paperH - this.ymargin(this.rectangle.attr("height") + y) || y <= 0)) {
				this.rectangle.attr("width", this.rectangle.attr("width") + x);
				this.rectangle.attr("height", this.rectangle.attr("height") + y);
				if (this.square) {
					
				}
				else {
					this.circle.attr("cx", this.circle.attr("cx") + x/2);
					this.circle.attr("rx", this.circle.attr("rx") + x/2);
					this.circle.attr("cy", this.circle.attr("cy") + y/2);
					this.circle.attr("ry", this.circle.attr("ry") + y/2);
					
					this.dashCircle.attr("cx", this.dashCircle.attr("cx") + x/2);
					this.dashCircle.attr("rx", this.dashCircle.attr("rx") + x/2);
					this.dashCircle.attr("cy", this.dashCircle.attr("cy") + y/2);
					this.dashCircle.attr("ry", this.dashCircle.attr("ry") + y/2);
				}
				this.corners[1].translate(x, 0);
				this.corners[2].translate(0, y);
				
				this.corners[this.draggingCorner].translate(x, y);
				this.inspectMargins();
			}
		}
	},
	dragRectangleStart: function (e) {
		if(e.preventDefault) {
			e.preventDefault();
		}
		this.setCursor('move');
		this.startx = e.clientX;
		this.starty = e.clientY;
		this.nowx = e.clientX;
		this.nowy = e.clientY;
		this.panning = true;
	},
	dragStart: function(e, i) {
		if(e.preventDefault) {
			e.preventDefault();
		}
		
		this.startx = e.clientX;
		this.starty = e.clientY;
		this.nowx = e.clientX;
		this.nowy = e.clientY;
		
		this.draggingCorner = i;
		
		this.dragging = true;
		this.setCursor(this.cornerData[i].cursor);
	},
	dragStartNW: function(e) {
		this.dragStart(e, 0);
	},
	dragStartNE: function(e) {
		
		this.dragStart(e, 1);
	},
	dragStartSW: function(e) {
		
		this.dragStart(e, 2);
	},
	dragStartSE: function(e) {
		
		this.dragStart(e, 3);
	},
	getWidth: function () {
		return this.rectangle.attr("width");
	},
	getHeight: function () {
		return this.rectangle.attr("height");
	},
	getX: function () {
		return this.rectangle.attr("x");
	},
	getY: function () {
		return this.rectangle.attr("y");
	},
	initHtml: function() {
		this.element = $('<div/>');
		this.paperDiv = $('<div/>');
		this.paperDiv.css({
			width: this.paperW + 'px',
			height: this.paperH + 'px',
			'float': 'left'
		});
		this.paper = Raphael(
			this.paperDiv.get(0),
			this.paperW,
			this.paperH
		);
		this.paper.image(
			this.item.getCropPreviewUrl(),
			0,
			0,
			this.paperW,
			this.paperH
		);
		this.element.append(this.paperDiv);
		
		this.square = this.item.varArray.stans.shape == 'suorakulmio';
		if (this.square) {
		
		}
		else {
			this.circle = this.paper.ellipse(
				this.cropPxX + this.cropPxW / 2,
				this.cropPxY + this.cropPxH / 2,
				this.cropPxW / 2,
				this.cropPxH / 2
			);
			this.circle.attr( {
				fill : "white",
				stroke : "white",
				"fill-opacity" : 0,
				"stroke-width" : 1
			});
			this.dashCircle = this.paper.ellipse(
				this.cropPxX + this.cropPxW / 2,
				this.cropPxY + this.cropPxH / 2,
				this.cropPxW / 2,
				this.cropPxH / 2
			);
			this.dashCircle.attr( {
				fill : "black",
				stroke : "black",
				"fill-opacity" : 0,
				"stroke-width" : 1,
				"stroke-dasharray": "- "
			});
		}
		
		this.rectangle = this.paper.rect(
			this.cropPxX,
			this.cropPxY,
			this.cropPxW,
			this.cropPxH
		);
		this.rectangle.attr( {
			fill : "#333333",
			stroke : "#333333",
			"fill-opacity" : 0,
			"stroke-width" : 1
		});
		this.rectangle.node.style.cursor = "move";
		this.rectangle.mouseover($.proxy(this.draggersShow, this));
		this.rectangle.mouseout($.proxy(this.mouseOffCrop, this));
		this.rectangle.mousedown($.proxy(this.dragRectangleStart, this));
		
		this.corners = [];
	
		for ( var i in this.cornerData) {
			/*console.log('initing corner', this.cornerData[i]);*/
			this.corners[i] = this.paper.rect(this.cornerData[i].x - 5, this.cornerData[i].y - 5, 10, 10);
			this.corners[i].attr( {
				fill : "#fff",
				stroke : "#4c4c4c",
				"fill-opacity" : 0,
				"stroke-opacity" : 0,
				"stroke-width" : 2
			});
			this.corners[i].node.style.cursor = this.cornerData[i].cursor;
			//corners[i].mousedown(dragger);
			// Add an index variable to all the shape objects
			this.corners[i].index = i;
			this.corners[i].mouseover($.proxy(this.draggersShow, this));
			this.corners[i].mouseout($.proxy(this.mouseOffCrop, this));
			this.corners[i].mousedown($.proxy(this.cornerData[i].drag, this));
		}
		
		
		this.toolbar = $('<div/>');
		this.toolbar.css({
			'float': 'left'
		});
		this.element.append(this.toolbar);
		
		this.centerWButton = $('<a>' + i18n.croperCenterW + '</a>');
		this.centerWButton.button({
			icons: {
				primary: 'ui-icon-arrowthick-2-e-w'
			}
		});
		this.centerWButton.click($.proxy(this.centerX, this));
		this.toolbar.append(this.centerWButton);
		this.toolbar.append('<br/>');
		this.centerHButton = $('<a>' + i18n.cropperCenterH + '</a>');
		this.centerHButton.button({
			icons: {
				primary: 'ui-icon-arrowthick-2-n-s'
			}
		});
		this.centerHButton.click($.proxy(this.centerY, this));
		this.toolbar.append(this.centerHButton);

		this.element.dialog({
			height: (this.paperH + 150),
			width: (this.paperW + 220),
			modal: true,
			title: i18n.cropperTitle,
			buttons: [
				{
					text: i18n.cropperDone,
					click: $.proxy(this.done, this)
				}
			]
		});
	},
	inspectMargins: function () {
		var y = 0;
		var x = 0;
		var cur_y_margin = this.ymargin(this.rectangle.attr("height"));
		var y_top = this.rectangle.attr("y");
		var y_bottom = y_top + this.rectangle.attr("height");
		var cur_x_margin = this.xmargin(this.rectangle.attr("width"));
		var x_left = this.rectangle.attr("x");
		var x_right = x_left + this.rectangle.attr("width");
		// yläreuna
		if (y_top < cur_y_margin) {
			y = cur_y_margin - y_top;
		}
		else if (y_bottom > this.paperH - cur_y_margin) {
			y = (this.paperH - cur_y_margin) - y_bottom;
		}
		if (x_left < cur_x_margin) {
			x = cur_x_margin - x_left;
		}
		else if (x_right > this.paperW - cur_x_margin) {
			x = (this.paperW - cur_x_margin) - x_right;
		}
		this.rectangle.translate(x, y);
		this.corners[0].translate(x, y);
		this.corners[1].translate(x, y);
		this.corners[2].translate(x, y);
		this.corners[3].translate(x, y);

		if (this.square) {
			
		}
		else {
			this.circle.translate(x, y);
			this.dashCircle.translate(x, y);
		}
	},
	mousemove: function(e) {
		if (this.dragging) {
			this.scaleBox(e.clientX - this.nowx, e.clientY - this.nowy);
			this.paper.safari();
			this.nowx = e.clientX;
			this.nowy = e.clientY;
		}
		else if(this.panning) {
			this.moveBox(e.clientX - this.nowx, e.clientY - this.nowy);
			this.paper.safari();
			this.nowx = e.clientX;
			this.nowy = e.clientY;
		}
	},
	mouseup: function() {
		this.dragging = false;
		this.panning = false;
		this.lastRequestedWidth = false;
		this.lastRequestedHeight = false;
		this.resetCursor();
	},
	mouseOffCrop: function () {
		if (this.hideDraggersTimer != null) {
			clearTimeout(this.hideDraggersTimer);
		}
		this.hideDraggersTimer = setTimeout($.proxy(this.draggersHide, this), 200);
	},
	moveBox: function(x, y) {
		if ((this.rectangle.attr("x") + x > this.xmargin(this.rectangle.attr("width") + x) || x >= 0) 
				&& (this.rectangle.attr("x") + this.rectangle.attr("width") + x < this.paperW - this.xmargin(this.rectangle.attr("width") + x) || x <= 0)) {
			this.rectangle.translate(x, 0);
			this.corners[0].translate(x, 0);
			this.corners[1].translate(x, 0);
			this.corners[2].translate(x, 0);
			this.corners[3].translate(x, 0);

			if (this.square) {
				
			}
			else {
				this.circle.translate(x, 0);
				this.dashCircle.translate(x, 0);
			}
		}
		if ((this.rectangle.attr("y") + y > this.ymargin(this.rectangle.attr("height") + y) || y >= 0)
				&& (this.rectangle.attr("y") + this.rectangle.attr("height") + y < this.paperH - this.ymargin(this.rectangle.attr("height") + y) || y <= 0)) {
			this.rectangle.translate(0, y);
			this.corners[0].translate(0, y);
			this.corners[1].translate(0, y);
			this.corners[2].translate(0, y);
			this.corners[3].translate(0, y);
			
			if (this.square) {
				
			}
			else {
				this.circle.translate(0, y);
				this.dashCircle.translate(0, y);
			}
		}
	},
	scaleBox: function(x, y) {
		if (this.lastRequestedHeight) {
			var requestedWidth = this.lastRequestedWidth + x * this.xMultipliers[this.draggingCorner];
			var requestedHeight = this.lastRequestedHeight + y  * this.yMultipliers[this.draggingCorner];
			this.lastRequestedWidth = requestedWidth;
			this.lastRequestedHeight = requestedHeight;
		}
		else {
			var requestedWidth = this.rectangle.attr("width") + x * this.xMultipliers[this.draggingCorner];
			var requestedHeight = this.rectangle.attr("height") + y * this.yMultipliers[this.draggingCorner];
			this.lastRequestedWidth = requestedWidth;
			this.lastRequestedHeight = requestedHeight;
		}
		// jos pyydetty kuvasuhde on pienempi kuin stanssin
		if ((requestedWidth / requestedHeight) < (this.item.varArray.stans.width / this.item.varArray.stans.height)) {
			var correctedWidth = this.item.varArray.stans.width * requestedHeight / this.item.varArray.stans.height;
			var correctedHeight = requestedHeight;
		}
		else {
			var correctedWidth = requestedWidth;
			var correctedHeight = this.item.varArray.stans.height * requestedWidth / this.item.varArray.stans.width;
		}
		var xMove = (correctedWidth - this.rectangle.attr("width")) * this.xMultipliers[this.draggingCorner];
		var yMove = (correctedHeight - this.rectangle.attr("height")) * this.yMultipliers[this.draggingCorner];
		this.draggingCornerMove(xMove, yMove);
	},
	setCursor: function (style) {
		/*console.log('Cropper', 'setCursor', style);*/
		this.rectangle.node.style.cursor = style;
		$("#cropCanvas").css('cursor', style);
		for ( var i = 0; i < 4; i++) {
			this.corners[i].node.style.cursor = style;
		}
	},
	setX: function (x) {
		var xtrans = x - this.rectangle.attr("x");
		this.rectangle.attr("x", x);
		for (i in this.corners) {
			this.corners[i].translate(xtrans, 0);
		}

		if (this.square) {
			
		}
		else {
			this.circle.translate(xtrans, 0);
			this.dashCircle.translate(xtrans, 0);
		}
	},
	setY: function (y) {
		var ytrans = y - this.rectangle.attr("y");
		this.rectangle.attr("y", y);
		for (i in this.corners) {
			this.corners[i].translate(0, ytrans);
		}
		if (this.square) {
			
		}
		else {
			this.circle.translate(0, ytrans);
			this.dashCircle.translate(0, ytrans);
		}
	},
	resetCursor: function () {
		/*console.log('Cropper', 'resetCursor');*/
		this.rectangle.node.style.cursor = "move";
		$("#cropCanvas").css('cursor', "default");
		for ( var i = 0; i < 4; i++) {
			this.corners[i].node.style.cursor = this.cornerData[i].cursor;
		}
	},
	xmargin: function(width) {
		return width * this.marginX;
	},
	ymargin: function(height) {
		return height * this.marginY;
	},
	done: function () {
		this.item.setCrop(this.getX(), this.getY(), this.getWidth(), this.getHeight(), $.proxy(this.doneCallback, this));
		/*console.log('Cropper', 'done');*/
	},
	doneCallback: function (data) {
		/*console.log('Cropper', 'doneCallback');*/
		if (data.success) {
			this.item.refreshPreview();
			$(document).unbind('mouseup');
			$(document).unbind('mousemove');
			this.element.dialog( "close" );
			this.element.dialog( "destroy" );
			this.element.remove();
		}
		else {
			$('<div><p>' + data.error + '</p></div>').dialog({
				modal: true,
				title: i18n.cropperErrorCropping,
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
					}
				}
			});
		}
	}
});
var DeleteDialog = $.klass({
	initialize: function(item, options) {
		this.options = {
		}
		this.item = item;
		$.extend(this.options, options);
		this.initHtml();
		return this;
	},
	initHtml: function() {
		this.element = $('<div/>');
		this.element.append('<p>' + i18n.deleteConfirm + '</p>')
		this.element.dialog({
			resizable: false,
			height:190,
			modal: true,
			buttons: [
				{
					text: i18n.deleteCancel,
					click: $.proxy(this.cancel, this)
				},
				{
					text: i18n.deleteConfirm,
					click: $.proxy(this.confirm, this)
				}
			],
			title: i18n.deleteTitle
		});
	},
	cancel: function () {
		/*console.log('DeleteDialog', 'cancel');*/
		this.element.dialog( "close" );
		this.element.dialog( "destroy" );
		this.element.remove();
	},
	confirm: function () {
		/*console.log('DeleteDialog', 'confirm');*/
		this.item.remove();
		this.element.dialog( "close" );
		this.element.dialog( "destroy" );
		this.element.remove();
	}
});
var LoggedModule = $.klass({
	initialize: function(element, options) {
		this.options = {
			logoutUrl: rootUrl + 'logout.php',
			loggedOutUrl: rootUrl + 'muokkaaTilaus'
		}
		this.element = element;
		$.extend(this.options, options);
		this.selectElements();
		this.bindEvents();
		return this;
	},
	bindEvents: function () {
		this.logoutButton.click($.proxy(this.logoutClick, this));
		this.ownInfoButton.click($.proxy(this.ownInfoClick, this));
	},
	logoutCallback: function (data) {
		if (data == '1') {
			window.location = this.options.loggedOutUrl;
		}
		else {
			alert(i18n.loggedAlreadyOut);
			window.location = this.options.loggedOutUrl;
		}
	},
	logoutClick: function (e) {
		e.preventDefault();
		this.logoutButton.removeClass('ui-state-focus');
		$.get(
			this.options.logoutUrl,
			$.proxy(this.logoutCallback, this)
		);
	},
	ownInfoClick: function (e) {
		e.preventDefault();
		this.ownInfoButton.removeClass('ui-state-focus');
		new OwnInfoDialog();
	},
	selectElements: function () {
		this.logoutButton = this.element.find('.logout');
		this.ownInfoButton = this.element.find('.ownInfo');
	}
});

FeedbackDialog = $.klass({
	initialize: function(options) {
		this.options = {
			ajaxUrl: rootUrl + 'feedback.php'
		}
		$.extend(this.options, options);
		this.initHtml();
		return this;
	},
	initHtml: function() {
		this.element = $('<div class="feedback"/>');
		this.form = $('<form method="post"> \
				<p>' + i18n.feedbackSubject + '</p> \
				<p><select name="aihe"> \
					<option value="0">' + i18n.feedbackChoose + '</option> \
					<option value="Kysymys">' + i18n.feedbackQuestion + '</option> \
					<option value="Palaute">' + i18n.feedbackFeedback + '</option> \
					<option value="Muu">' + i18n.feedbackOther + '</option> \
				</select></p> \
				<p>' + i18n.feedbackName + '<br/> \
				<input name="nimi" type="text"></p> \
				<p>' + i18n.feedbackCompany + '<br/> \
				<input name="yritys" type="text"></p> \
				<p>' + i18n.feedbackTel + '<br/> \
				<input name="puhelinnumero" type="text"></p> \
				<p>' + i18n.feedbackEmail + '<br/> \
				<input name="sähköposti" type="text"></p> \
				<p>' + i18n.feedbackMessage + '<br/> \
				<textarea name="viesti"></textarea></p> \
			</form>');
		this.element.append(this.form);
		this.element.dialog({
			resizable: false,
			height: 535,
			modal: true,
			buttons: [
				{
					text: i18n.feedbackCancel,
					click: $.proxy(this.cancel, this)
				},
				{
					text: i18n.feedbackSend,
					click: $.proxy(this.send, this)
				}
			],
			title: i18n.feedbackTitle
		});
	},
	cancel: function () {
		/*console.log('DeleteDialog', 'cancel');*/
		this.element.dialog( "close" );
		this.element.dialog( "destroy" );
		this.element.remove();
	},
	send: function () {
		/*console.log('DeleteDialog', 'confirm');*/
		$.post(
			this.options.ajaxUrl,
			this.form.serializeArray(),
			$.proxy(this.sentCallback, this),
			'json'
		);
		
	},
	sentCallback: function (data) {
		/*console.log(data);*/
		if (data.success) {
			this.element.dialog( "close" );
			this.element.dialog( "destroy" );
			this.element.remove();
			$('<div><p>' + i18n.feedbackThanks + '</p></div>').dialog({
				modal: true,
				title: i18n.feedbackDone,
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
						$( this ).remove();
					}
				}
			});
		}
		else {
			$('<div><p>' + i18n.feedbackTryAgain + '</p></div>').dialog({
				modal: true,
				title: i18n.feedbackError,
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
						$( this ).remove();
					}
				}
			});
		}
	}
});
var LoginModule = $.klass({
	initialize: function(element, options) {
		this.options = {
			url: rootUrl + 'login.php',
			redirectUrl: rootUrl + 'muokkaaTilaus'
		}
		this.element = element;
		$.extend(this.options, options);
		this.selectElements();
		this.bindEvents();
		return this;
	},
	bindEvents: function () {
		this.registerButton.click($.proxy(this.registerButtonClick, this));
		
		this.forgotPwButton.click($.proxy(this.forgotPwClick, this));
		
		this.form.submit($.proxy(this.loginClick, this));
		this.loginButton.click($.proxy(this.loginClick, this));
		this.loginButton.css('font-size', '9pt');
		this.loginButton.css('padding', '0.1em 0.8em');
		
		this.emailFieldDefault = this.emailInput.val();
 
		this.passwordPlaceholder = $('<input type="text" value="' + i18n.password + '" autocomplete="off" />');
	    // add a password placeholder field to the html
	    this.passwordInput.after(this.passwordPlaceholder);
	    
	 
	    // show the placeholder with the prompt text and hide the actual password field
	    this.passwordPlaceholder.show();
	    this.passwordInput.hide();
	
	    // when focus is placed on the placeholder hide the placeholder and show the actual password field
	    this.passwordPlaceholder.focus($.proxy(this.pwFocus, this));
	    // and vice versa: hide the actual password field if no password has yet been entered
	    this.passwordInput.blur($.proxy(this.pwBlur, this));
	 
	    // when focus goes to and moves away from the email field, reset it to blank or restore the default depending if a value is entered
	    this.emailInput.focus($.proxy(this.emailFocus, this));
	    this.emailInput.blur($.proxy(this.emailBlur, this));

	},
	forgotPwClick: function (e) {
		e.preventDefault();
		this.forgotPwButton.removeClass('ui-state-focus');
		new PasswordDialog();
	},
    emailFocus: function () {
        if(this.emailInput.val() == this.emailFieldDefault) {
            this.emailInput.val('');
        }
    },
    emailBlur: function() {
        if(this.emailInput.val() == '') {
            this.emailInput.val(this.emailFieldDefault);
        }
    },
	loginCallback: function (data) {
		if (data == '2') {
			window.location = this.options.redirectUrl
		}
		else if (data == '1') {
			alert(i18n.loginCheckPassword);
		}
		else {
			alert(i18n.loginUserNoFound);
		}
	},
	loginClick: function (e) {
		e.preventDefault();
		var valid = true;
		if (this.passwordInput.val().length < 1) {
			valid = false;
			this.passwordInput.parent().parent().addClass('error');
		}
		else {
			this.passwordInput.parent().parent().removeClass('error');
		}
		if (this.emailInput.val().length < 1) {
			valid = false;
			this.emailInput.parent().parent().addClass('error');
		}
		else {
			this.emailInput.parent().parent().removeClass('error');
		}
		if (valid) {
			$.get(
				this.options.url,
				{
					email: this.emailInput.val(),
					pass: this.passwordInput.val()
				},
				$.proxy(this.loginCallback, this)
			);
		}
		else {
			alert(i18n.loginCheckFields);
		}
	},
	pwFocus: function () {
        this.passwordPlaceholder.hide();
        this.passwordInput.show();
        this.passwordInput.focus();
	},
	pwBlur: function() {
        if(this.passwordInput.val() == '') {
            this.passwordPlaceholder.show();
            this.passwordInput.hide();
        }
    },
	registerButtonClick: function (e) {
		e.preventDefault();
		this.registerButton.removeClass('ui-state-focus');
		new RegisterDialog();
	},
	selectElements: function () {
		this.form = this.element.find('form');
		this.emailInput = this.element.find('.email');
		this.passwordInput = this.element.find('.password');
		this.loginButton = this.element.find('.loginSubmit');
		this.registerButton = this.element.find('.register');
		this.forgotPwButton = this.element.find('.forgotPw');
	}
});
var OwnInfoDialog = $.klass({
	initialize: function(options) {
		this.options = {
			formUrl: rootUrl + 'userEdit.php',
			saveUrl: rootUrl + 'editUserData.php'
		}
		$.extend(this.options, options);
		this.loadHtml();
		return this;
	},
	initHtml: function(data) {
		
		this.element.html(data);
		this.element.find('#company').focus();
	},
	loadHtml: function () {
		this.element = $('<div class="checkout"/>');
		this.element.html('<img src="' + rootUrl + 'images/loading.gif" />');
		this.element.dialog({
			width: 400,
			height: 400,
			modal: true,
			buttons: [
				{
					text: i18n.feedbackCancel,
					click: $.proxy(this.close, this)
				},
				{
					text: i18n.ownInfoSave,
					click: $.proxy(this.save, this)
				}
			],
			title: i18n.ownInfoTitle
		});
		$.get(
			this.options.formUrl,
			$.proxy(this.initHtml, this)
		);
	},
	cancel: function () {
		$.get(
			this.options.cancelUrl,
			{offer: cart.id}
		);
	},
	close: function () {
		this.element.dialog( "close" );
		this.element.dialog( "destroy" );
		this.element.remove();
	},
	save: function () {
		var data = this.element.find('form').serializeArray();
		$.getJSON(
			this.options.saveUrl,
			data,
			$.proxy(this.saveCallback, this)
		);
		this.element.dialog( 'option', 'buttons', [
			{
				text: i18n.feedbackCancel,
				click: $.proxy(this.close, this)
			}
		]);
		this.element.html('<img src="' + rootUrl + 'images/loading.gif" />');
	},
	saveCallback: function (data) {
		if (data.success) {
			this.close();
		}
		else {
			$('<div><p>' + i18n.ownInfoErrorSaving + ' ' + data.error + '</p></div>').dialog({
				modal: true,
				title: i18n.error,
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
					}
				}
			});
			$.get(
				this.options.formUrl,
				$.proxy(this.initHtml, this)
			);
			this.element.dialog( 'option', 'buttons', [
				{
					text: i18n.feedbackCancel,
					click: $.proxy(this.close, this)
				},
				{
					text: i18n.ownInfoSave,
					click: $.proxy(this.save, this)
				}
			]);
			
		}
	}
});
var Preview = $.klass({
	initialize: function(element, options) {
		this.options = {
			w: 382,
			h: 332,
			imgMaxW: 310,
			imgMaxH: 310,
			previewScript: '/previewImage.php?order=',
			tooltipSelector: '#stansTooltip',
			deleteCallback: function () {},
			cropCallback: function () {}
		}
		this.element = element;
		$.extend(this.options, options);
		this.selectElements();
		this.initHtml();
		this.bindEvents();
		this.paper = Raphael(this.element.get(0), this.options.width, this.options.height);
		this.stans = null;
		this.cutout = null;
		this.blackStroke = null;
		this.whiteDashStroke = null;
		this.image = null;
		
		this.item = null;
	},
	bindEvents: function () {
		this.cropButton.click($.proxy(this.cropClick, this));
		this.deleteButton.click($.proxy(this.deleteClick, this));
	},
	cropClick: function (e) {
		e.preventDefault();
		/*console.log('Preview', 'cropClick');*/
		if (this.item != null && this.item.varArray.placeholder == false && this.item.varArray.state != 'upload') {
			var cropper = new Cropper(this.item);
			this.options.cropCallback(this.item);
		}
		else {
			$('<div><p>' + i18n.noPictures + '</p></div>').dialog({
				modal: true,
				title: 'Info',
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
					}
				}
			});

		}
	},
	deleteClick: function (e) {
		e.preventDefault();
		/*console.log('Preview', 'deleteClick');*/
		if (this.item != null) {
			var cropper = new DeleteDialog(this.item);
			this.options.deleteCallback(this.item);
		}
		else {
			$('<div><p>' + i18n.noPictures + '</p></div>').dialog({
				modal: true,
				title: 'Info',
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
					}
				}
			});

		}
	},
	selectElements: function () {
		this.tooltip = $(this.options.tooltipSelector);
		this.cropButton = $('.cropper');
		this.deleteButton = $('.delete');
	},
	update: function() {
		this.paper.clear();
		Preview.activeInstance = this;
		$("<img />")
			.attr("src", this.options.previewScript + i + "&size=310&r=" + Math.random())
			.load(this.imageCachedCallback);
	},
	/**
	 * funktiota kutsutaan kuvan kontekstissa
	 */
	imageCachedCallback: function() {
		Preview.activeInstance.setCachedImage(this);
	},
	initHtml: function () {
		this.cropButton.button({
			icons: {primary: 'ui-icon-arrow-4-diag'},
			text: false
		});
		this.deleteButton.button({
			icons: {primary: 'ui-icon-closethick'},
			text: false
		});
	},
	calculateCut: function () {
		this.cutW = this.options.imgMaxW;
	    this.cutH = this.options.imgMaxH;
	    
		var w = this.stans.width + this.stans.margin_x * 2;
		var h = this.stans.height + this.stans.margin_y * 2;
		
		if (h < w) {
			this.cutH = Math.round(h / w * this.options.imgMaxW);
		}
		else {
			this.cutW = Math.round(w / h * this.options.imgMaxH);
		}
	},
	clearStans: function () {
		if (this.cutout != null) {
			this.cutout.remove()
		}
		if (this.blackStroke != null) {
			this.blackStroke.remove()
		}
		if (this.whiteDashStroke != null) {
			this.whiteDashStroke.remove()
		}
	},
	setItem: function (item) {
		// jos oli jo itemi
		if (this.item != null) {
			//edelliseltä itemiltä reload callback pois
			this.item.options.reloadCallback = function () {};
		}
		/*console.log('Preview', 'setItem', item);*/
		this.item = item;
		this.item.options.reloadCallback = $.proxy(this.reloadImage, this);
		this.stans = this.item.varArray.stans;
		
		this.calculateCut();
		//this.reloadImage();
		this.setStans(item.varArray.stans);
		this.reloadImage();
	},
	reloadImage: function () {
		/*console.log('Preview', 'reloadImage');*/
		if (this.image != null) {
			this.image.remove();
		}
		/*console.log(
			this.item.getPreviewImgUrl()
		);*/
		if (!this.item.varArray.placeholder) {
			this.image = this.paper.image(
				this.item.getPreviewImgUrl(), 
				(this.options.imgMaxW - this.cutW) / 2, 
				(this.options.imgMaxH - this.cutH) / 2,
				this.cutW, 
				this.cutH
			);
			
		    this.image.translate((this.element.width() - this.options.imgMaxW) / 2, (this.element.height() - this.options.imgMaxH) / 2);
		    this.image.toBack();
		}
	},
	removeItem: function () {
		if (this.image != null) {
			this.image.remove();
		}
		this.item = null;
		
	},
	setStans: function (stans) {
		/*console.log('Preview', 'setStans', stans);*/
		
		this.stans = stans;
		this.clearStans();
		var circleExtra = '';
	    if (stans.shape != 'suorakulmio') {
	    	circleExtra = 'M 0 0 z ';
	    }
	    
		this.calculateCut();
		
	    this.cutout = this.paper.path(
	    	'M ' + ((this.options.imgMaxW - this.cutW) / 2) + ' ' + ((this.options.imgMaxH - this.cutH) / 2) + 
	    	' L ' + ((this.options.imgMaxW - this.cutW) / 2) + ' ' + (this.cutH + (this.options.imgMaxH - this.cutH) / 2) + 
	    	' L ' + (this.cutW + (this.options.imgMaxW - this.cutW) / 2) + ' ' + (this.cutH + (this.options.imgMaxH - this.cutH) / 2) + 
	    	' L ' + (this.cutW + (this.options.imgMaxW - this.cutW) / 2) + ' ' + ((this.options.imgMaxH - this.cutH) / 2) + 
	    	' L ' + ((this.options.imgMaxW - this.cutW) / 2) + ' ' + ((this.options.imgMaxH - this.cutH) / 2) + 
	    	' z ' + circleExtra + stans.svg);
	    this.cutout.attr({
	    	fill: "black",
	    	opacity: .5
	    });
	    this.cutout.translate((this.element.width() - this.options.imgMaxW) / 2, (this.element.height() - this.options.imgMaxH) / 2);
	    
	    this.cutout.mouseover($.proxy(this.mouseOverCutout, this));
	    this.cutout.mouseout($.proxy(this.mouseOutCutout, this));
	    
	    this.blackStroke = this.paper.path(stans.svg);
	    this.blackStroke.attr({stroke: "#000"});
	    this.blackStroke.translate((this.element.width() - this.options.imgMaxW) / 2, (this.element.height() - this.options.imgMaxH) / 2);
	    
	    this.whiteDashStroke = this.paper.path(stans.svg);
	    this.whiteDashStroke.attr({stroke: "#FFF", "stroke-dasharray": "- "});
	    this.whiteDashStroke.translate((this.element.width() - this.options.imgMaxW) / 2, (this.element.height() - this.options.imgMaxH) / 2);
	},
	mouseOverCutout: function() {
    	var offset = this.element.offset();
    	this.tooltip.css({
    		position: 'absolute',
    		top: (offset.top + this.element.height()) + 'px',
    		left: offset.left,
    		display: 'block'
    	});
    },
    mouseOutCutout: function() {
    	this.tooltip.css({
    		display: 'none'
    	});
    }
});
var PreviewDialog = $.klass({
	initialize: function(item, options) {
		this.options = {
			size: 310
		}
		this.item = item;
		$.extend(this.options, options);
		this.calculateCut();
		this.initHtml();
		return this;
	},
	calculateCut: function () {
		this.cutW = this.options.size;
	    this.cutH = this.options.size;
	    
		var w = this.item.varArray.stans.width + this.item.varArray.stans.margin_x * 2;
		var h = this.item.varArray.stans.height + this.item.varArray.stans.margin_y * 2;
		
		if (h < w) {
			this.cutH = Math.round(h / w * this.options.size);
		}
		else {
			this.cutW = Math.round(w / h * this.options.size);
		}
	},
	initHtml: function() {
		this.element = $('<div/>');
		this.paperDiv = $('<div/>');
		this.paperDiv.css({
			width: this.options.size + 'px',
			height: this.options.size + 'px',
			'float': 'left'
		});
		this.paper = Raphael(
			this.paperDiv.get(0),
			this.options.size,
			this.options.size
		);
		this.image = this.paper.image(
			this.item.getPreviewImgUrl(),
			0,
			0,
			this.cutW,
			this.cutH
		);
	    this.image.translate((this.options.size - this.cutW) / 2, (this.options.size - this.cutH) / 2);
		var circleExtra = '';
		
	    if (this.item.varArray.stans.shape != 'suorakulmio') {
	    	circleExtra = 'M 0 0 z ';
	    }
	    
	    this.cutout = this.paper.path(
	    	'M 0 0' + 
	    	' L 0 ' + this.options.size + 
	    	' L ' + this.options.size + ' ' + this.options.size + 
	    	' L ' + this.options.size + ' 0' + 
	    	' L 0 0' + 
	    	' z ' + circleExtra + this.item.varArray.stans.svg);
	    this.cutout.attr({
	    	fill: "white",
	    	stroke: "none"
	    });
	    this.cutout.translate((this.paperDiv.width() - this.options.size) / 2, (this.paperDiv.height() - this.options.size) / 2);
	    
		
		
		this.element.append(this.paperDiv);
		this.element.dialog({
			height: this.options.size + 130,
			width: this.options.size + 35,
			modal: true,
			buttons: [
				{
					text: 'Ok',
					click: $.proxy(this.close, this)
				}
			],
			title: i18n.preview
		});
	},
	close: function () {
		/*console.log('DeleteDialog', 'cancel');*/
		this.element.dialog( "close" );
		this.element.dialog( "destroy" );
		this.element.remove();
	}
});
var RegisterDialog = $.klass({
	initialize: function(options) {
		this.options = {
			submitUrl: rootUrl + 'createUser.php'
		}
		$.extend(this.options, options);
		this.loadHtml();
		return this;
	},
	loadHtml: function () {
		this.element = $('<div class="checkout"/>');
		this.element.dialog({
			width: 400,
			height: 440,
			modal: true,
			buttons: [
				{
					text: i18n.feedbackCancel,
					click: $.proxy(this.close, this)
				},
				{
					text: i18n.registerSave,
					click: $.proxy(this.save, this)
				}
			],
			title: i18n.registerTitle
		});
		this.initHtml();
	},
	cancel: function () {
		$.get(
			this.options.cancelUrl,
			{offer: cart.id}
		);
	},
	countryOptions: function () {
		var html = "";
		var sHtml;
		$.each(countries, function(i, val) {
			if (val == "Finland" || val == "Suomi") {
				sHtml = ' selected="selected"';
			}
			else {
				sHtml = "";
			}
			html += '<option value="' + i + '"' + sHtml + '>' + val + '</option>';
	    })
	    return html;
	},
	close: function () {
		this.element.dialog( "close" );
		this.element.dialog( "destroy" );
		this.element.remove();
	},
	initHtml: function () {
		var html = '';
		html += '<form>';
		html += '<table>';
		html += '<tr><td>' + i18n.email + '</td><td><input type="text" name="email" id="rEmail" value="" /></td></tr>';
		html += '<tr><td>' + i18n.password + '</td><td><input type="password" name="password" id="rPassword" /></td></tr>';
		html += '<tr><td>' + i18n.company + '</td><td><input type="text" name="company" id="rCompany" /></td></tr>';
		html += '<tr><td>' + i18n.firstName + '</td><td><input type="text" name="first_name" id="rFirstName" /></td></tr>';
		html += '<tr><td>' + i18n.lastName + '</td><td><input type="text" name="last_name" id="rLastName" /></td></tr>';
		html += '<tr><td>' + i18n.address + '</td><td><input type="text" name="address" id="rAddress" /></td></tr>';
		html += '<tr><td>' + i18n.city + '</td><td><input type="text" name="city" id="rCity" /></td></tr>';
		html += '<tr><td>' + i18n.zip + '</td><td><input type="text" name="zip" id="rZip" /></td></tr>';
		html += '<tr><td>' + i18n.country + '</td><td><select id="rCountry">' + this.countryOptions() + '</select></td></tr>';
		html += '<tr><td>' + i18n.phone + '</td><td><input type="text" name="phone" id="rPhone" /></td></tr>';
		html += '</table>';
		html += '</form>';
		this.element.html(html);
		this.element.find('#rEmail').focus();
	},
	save: function () {
		var data = this.element.find('form').serializeArray();
		$.getJSON(
			this.options.submitUrl,
			data,
			$.proxy(this.saveCallback, this)
		);
		this.element.dialog( 'option', 'buttons', [
			{
				text: i18n.feedbackCancel,
				click: $.proxy(this.close, this)
			}
		]);
		this.element.html('<img src="' + rootUrl + 'images/loading.gif" />');
	},
	saveCallback: function (data) {
		if (data.success) {
			window.location.reload();
		}
		else {
			$('<div><p>' + i18n.errorSaving + ' ' + data.error + '</p></div>').dialog({
				modal: true,
				title: i18n.error,
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
					}
				}
			});
			
		}
	}
});
var PasswordDialog = $.klass({
	initialize: function(options) {
		this.options = {
			submitUrl: rootUrl + 'resetPassword.php'
		}
		$.extend(this.options, options);
		this.loadHtml();
		return this;
	},
	loadHtml: function () {
		this.element = $('<div class="checkout"/>');
		this.element.dialog({
			width: 400,
			height: 150,
			modal: true,
			buttons: [
				{
					text: i18n.feedbackCancel,
					click: $.proxy(this.close, this)
				},
				{
					text: i18n.passwordRestore,
					click: $.proxy(this.submit, this)
				}
			],
			title: i18n.passwordTitle
		});
		this.initHtml();
	},
	cancel: function () {
		$.get(
			this.options.cancelUrl,
			{offer: cart.id}
		);
	},
	close: function () {
		this.element.dialog( "close" );
		this.element.dialog( "destroy" );
		this.element.remove();
	},
	initHtml: function () {
		var html = '';
		html += '<form>';
		html += '<table>';
		html += '<tr><td>' + i18n.email + '</td><td><input type="text" name="email" id="resetEmail" value="" /></td></tr>';
		html += '</table>';
		html += '</form>';
		this.element.html(html);
		this.element.find('#resetEmail').focus();
	},
	submit: function () {
		this.gotEmail = this.element.find('#resetEmail').val();
		var data = this.element.find('form').serializeArray();
		$.getJSON(
			this.options.submitUrl,
			data,
			$.proxy(this.submitCallback, this)
		);
		this.element.dialog( 'option', 'buttons', [
			{
				text: i18n.feedbackCancel,
				click: $.proxy(this.close, this)
			}
		]);
		this.element.html('<img src="' + rootUrl + 'images/loading.gif" />');
	},
	submitCallback: function (data) {
		if (data.success) {
			this.close();
			$('<div><p>' + i18n.pwResetSent + '</p></div>').dialog({
				modal: true,
				title: i18n.passwordDone,
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
					}
				}
			});
		}
		else {
			$('<div><p>' + data.error + '</p></div>').dialog({
				modal: true,
				title: i18n.error,
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
					}
				}
			});
			this.initHtml();
			this.element.dialog( 'option', 'buttons', [
				{
					text: i18n.feedbackCancel,
					click: $.proxy(this.close, this)
				},
				{
					text: i18n.passwordRestore,
					click: $.proxy(this.submit, this)
				}
			]);
			this.element.find('#resetEmail').val(this.gotEmail);
		}
	}
});
var StansChooser = $.klass({
	initialize: function (element, options) {
		this.options = {
			stansOptionsUrl: rootUrl + 'muokkaaTilaus/stanssiVaihtoehdot/'
			
		}
		this.element = element;
		$.extend(this.options, options);
		this.chooseCallback = null;
		this.updateTimer = null;
		this.loadedW = null;
		this.loadedH = null;
		this.loadedS = null;
		this.lastChosenStans = null;
		this.wasCustom = false;
		this.ingoreStansUpdate = false;
		this.selectElements();
		this.bindEvents();
	},
	bindEvents: function () {
		this.form.bind('submit', $.proxy(this.updateStansListForce, this));
		this.wInput.bind('keyup change', $.proxy(this.sizeChanged, this));
		this.hInput.bind('keyup change', $.proxy(this.sizeChanged, this));
		this.shapeInput.bind('change', $.proxy(this.sizeChanged, this));
		this.customInput.bind('change', $.proxy(this.sizeChanged, this));
		this.stansSelect.bind('change', $.proxy(this.setStans, this));
	},
	selectElements: function () {
		this.form = this.element.find('form');
		this.wInput = this.element.find('#stansWidth');
		this.hInput = this.element.find('#stansHeight');
		this.shapeInput = this.element.find('#stansShape');
		this.customInput = this.element.find('#stansCustom');
		this.stansSelect = this.element.find('#stansSelect');
	},
	selectStans: function (stans) {
		/*console.log('StansChooser', 'selectStans', stans);*/
		this.wInput.val(stans.width);
		this.hInput.val(stans.height);
		this.shapeInput.val(stans.shape);
		if (!stans.available) {
			this.customInput.attr('checked', 'checked');
			this.stansSelect.find('option:selected').removeAttr('selected');
			this.stansSelect.attr('disabled', 'disabled');
			this.wasCustom = true;
		}
		else {
			this.customInput.removeAttr('checked');
			this.stansSelect.removeAttr('disabled');
			this.ingoreStansUpdate = true;
			this.updateStansListForce();
		}
	},
	setChooseCallback: function(callback) {
		this.chooseCallback = callback;
	},
	setStans: function () {
		if (!this.ingoreStansUpdate) {
			// jos valittu omilla mitoilla
			if (this.customInput.get(0).checked) {
				var w = parseFinnishFloat(this.wInput.val());
				var h = parseFinnishFloat(this.hInput.val());
				var shape = this.shapeInput.val();
				if (w > 0 && h > 0 && shape != '' && this.chooseCallback != null) {
					this.chooseCallback(true, {
						w: w,
						h: h,
						shape: shape
					});
				}
			}
			// valittu stanssi listasta
			else {
				var stansId = null;
				var found = false;
				this.stansSelect.find('option:selected').each(function () {
					if (!found) {
						stansId = this.value;
						found = true;
					}
					else {
						//$(this).removeAttr("selected");
					}
				});
				if (stansId != this.lastChosenStans && stansId != null && this.chooseCallback != null) {
					this.chooseCallback(false, stansId);
					this.lastChosenStans = stansId;
				}
			}
		}
		else {
			this.ingoreStansUpdate = false;
		}
	},
	sizeChanged: function () {
		if (this.updateTimer != null) {
			clearTimeout(this.updateTimer);
		}
		// jos valittu omilla mitoilla
		if (this.customInput.get(0).checked) {
			this.stansSelect.find('option:selected').removeAttr('selected');
			this.stansSelect.attr('disabled', 'disabled');
			
			var width = parseFinnishFloat(this.wInput.val());
			var height = parseFinnishFloat(this.hInput.val());
			var shape = this.shapeInput.val();
			// jos vasta vaihdettiin custom tilaan tai koko tai muoto vaihtunut
			if (!this.wasCustom || (width != this.loadedW || height != this.loadedH || this.loadedS != shape)) {
				
				this.loadedW = width;
				this.loadedH = height;
				this.loadedS = shape;
				if (width > 0 && height > 0 && this.chooseCallback != null) {
					this.chooseCallback(true, {width: width, height: height, shape: shape});
				}
			}
			this.wasCustom = true;
		}
		else {
			if (this.wasCustom) {
				this.stansSelect.removeAttr('disabled');
				this.updateStansListCallback();
				this.wasCustom = false;
			}
			this.updateTimer = setTimeout($.proxy(this.updateStansList, this), 600);
		}
	},
	updateStansList: function () {
		var width = parseFinnishFloat(this.wInput.val());
		var height = parseFinnishFloat(this.hInput.val());
		var shape = this.shapeInput.val();
		if (width > 0 && height > 0 && (width != this.loadedW || height != this.loadedH || this.loadedS != shape) && this.stansSelect != null) {
			this.stansSelect.load(
				this.options.stansOptionsUrl + width + '/' + height + '/' + shape,
				$.proxy(this.updateStansListCallback, this)
			);
			this.loadedW = width;
			this.loadedH = height;
			this.loadedS = shape;
		}
	},
	updateStansListCallback: function () {
		var width = parseFinnishFloat(this.wInput.val());
		var height = parseFinnishFloat(this.hInput.val());
		this.stansSelect.find('option').bind('click', $.proxy(this.setStans, this));
		// jos löytyy täsmälleen halutun kokoinen stanssi
		if (this.stansSelect.find("option:contains('"+ width + " x " + height + "')").length > 0) {
			// poistetaan muut valinnat
			this.stansSelect.find('option').removeAttr("selected");
			// valitaan
			this.stansSelect.find("option:contains('"+ width + " x " + height + "')").attr("selected", "selected");
		}
		this.setStans();
		this.customInput.removeAttr('checked');
	},
	updateStansListForce: function () {
		if (this.updateTimer != null) {
			clearTimeout(this.updateTimer);
		}
		this.updateStansList();
	}
});

var Cart = $.klass({
	initialize: function (element, options) {
		this.options = {
			stansChooser: null,
			previewArea: null,
			countChooser: null
		}
		this.element = element;
		$.extend(this.options, options);
		
		this.flashIsLoaded = false;
		this.setStansId = null;
		
		this.selectElements();
		this.bindEvents();
		if (this.options.previewArea != null) {
			this.initUploader();
		}
		if (this.options.stansChooser != null) {
			this.options.stansChooser.setChooseCallback($.proxy(this.setStans, this));
		}
		this.items = {};
		this.itemCount = 0;
		this.uploadingFiles = {};
		this.activeItem = null;
		this.updateOfferInfo();
	},
	
	/**
	 * Callbacki itemin aktivointiin
	 * @param CartItem item
	 */
	activateCartItem: function (item) {
		/*console.log('activateCartItem', item);*/
		if (this.options.previewArea != null) {
			this.options.previewArea.setItem(item);
		}
		if (this.options.countChooser != null) {
			this.options.countChooser.setCartItem(item);
		}
		$.each(this.items, function () {
			// tässä this viittaa each loopin keyhyn
			if (item.varArray.id != this.varArray.id) {
				this.deactivate();
			}
		});
		this.activeItem = item;
		if (this.options.stansChooser != null) {
			this.options.stansChooser.selectStans(this.activeItem.varArray.stans);
		}
		this.updateOfferInfo();
		this.materialButton.attr('href', rootUrl + 'muokkaaTarraa/' + this.activeItem.varArray.id);
	},
	addSavedItem: function (varArray) {
		/*console.log('addSavedItem', varArray);*/
		var item = new CartItem(
			varArray,
			{
				activateCallback: $.proxy(this.activateCartItem, this),
				initHtmlCallback: $.proxy(this.insertCartItemHtml, this),
				uploadSuccess: $.proxy(this.uploadSuccess, this),
				deleteCallback: $.proxy(this.itemDeleteCallback, this),
				startPriceMethod: $.proxy(this.getStartPriceShare, this),
				updateOfferInfo: $.proxy(this.updateOfferInfo, this)
			}
		);
		// lisätään itemeihin
		this.items[item.varArray.id] = item;
		
		if (this.activeItem == null || this.activeItem.varArray.placeholder) {
			item.activate();
		}
		return item;
	},
	bindEvents: function() {
		this.previewElement.click($.proxy(this.previewClick, this));
		this.materialButton.click($.proxy(this.materialClick, this));
		this.orderButton.click($.proxy(this.orderClick, this));
	},
	fileUploadSuccess: function(file, data, response) {
		/*console.log(file, data, response);*/
		var item = this.uploadingFiles[file.id];
		
		// poistetaan uploadiintuvista
		var newFiles = {};
		$.each(this.uploadingFiles, function (key, val) {
			if (key != file.id) {
				newFiles[key] = val;
			}
		});
		this.uploadingFiles = newFiles;
		// stanssin asetus
		if (this.options.previewArea != null && this.options.previewArea.stans != null) {
			item.stans = this.options.previewArea.stans;
		}
		
		// päivitetään itemin tiedot palvelimelta tulleiksi
		data = $.parseJSON(data);
		item.uploadSuccess(data);
		
		
		// lisätään itemeihin
		this.items[item.varArray.id] = item;
		this.options.countChooser.updatePrices();
	},
	fileUploadProgress: function(file, bytes, total) {
		/*console.log(file, bytes, total);*/
		this.uploadingFiles[file.id].uploadProgress(bytes, total);
	},
	fileQueue: function(file){
		if (this.activeItem != null) {
			// asetetaan stanssi uploaderiin
			/*console.log('Cart', 'activateCartItem', 'setting stans to uploader:', this.activeItem.varArray.stans.id);*/
			this.uploader.getInstance().addPostParam('stansId', this.activeItem.varArray.stans.id);
		}
		this.uploadingFiles[file.id] = new CartItem(
			{
				state: 'upload',
				uploadingFile: file
			},
			{
				activateCallback: $.proxy(this.activateCartItem, this),
				initHtmlCallback: $.proxy(this.insertCartItemHtml, this),
				uploadSuccess: $.proxy(this.uploadSuccess, this),
				deleteCallback: $.proxy(this.itemDeleteCallback, this),
				startPriceMethod: $.proxy(this.getStartPriceShare, this),
				priceUpdateCallback: $.proxy(this.options.countChooser.updateCurrentPrice, this.options.countChooser),
				updateOfferInfo: $.proxy(this.updateOfferInfo, this)
			}
		);
		/*
		var self = this;
		$.each(this.items, function () {
			if (this.varArray.placeholder) {
				self.removeItem(this);
				this.remove();
			}
		});
		*/
	},
	flashLoaded: function () {
		/*console.log('Cart', 'flashLoaded');*/
		this.flashIsLoaded = true;
		if (this.setStansId != null) {
			/*console.log('flashLoaded', 'stansId', this.setStansId);*/
			this.uploader.getInstance().addPostParam('stansId', this.setStansId);
		}
	},
	getStansChooser: function () {
		return this.options.stansChooser;
	},
	getStartPriceShare: function () {
		var startPrice = startingPrice;
		
		var usedStanses = [];
		
		var count = 0;
		var items = this.items;
		$.each(items, function () {
			if (!this.varArray.placeholder) {
				// jos tämä ei ole eka itemi
				if (count != 0) {
					// lisätään summaan kuvanvaihtohinta
					startPrice += imageChangePrice;
				}
				// jos tätä stanssia ei käytetty vielä tilauksessa
				if ($.inArray(this.varArray.stans.id, usedStanses) == -1) {
					// lisätään käytettyjen stanssien listaan
					usedStanses.push(this.varArray.stans.id);
					// jos tämä ei ole eka itemi
					if (count != 0) {
						// lisätään stanssin vaihtohinta
						startPrice += stansChangePrice;
					}
				}
				
				count++;
			}
		});
		var uploading = this.uploadingFiles;
		$.each(uploading, function (key, val) {
			// jos tämä ei ole eka itemi
			if (count != 0) {
				// lisätään summaan kuvanvaihtohinta
				startPrice += imageChangePrice;
			}
			// jos tätä stanssia ei käytetty vielä tilauksessa
			if ($.inArray(this.setStansId, usedStanses) == -1) {
				// lisätään käytettyjen stanssien listaan
				usedStanses.push(this.setStansId);
				// jos tämä ei ole eka itemi
				if (count != 0) {
					// lisätään stanssin vaihtohinta
					startPrice += stansChangePrice;
				}
			}
			
			count++;
		});
		count = count == 0 ? 1 : count; // jos vasta placeholder, tarvitaan placeholder ykkönen
		return Math.round((startPrice / count) * 100) / 100;
	},
	hasStansChooser: function() {
		return this.options.stansChooser != null;
	},
	initUploader: function() {
		this.uploader = new MultiUpload(this.uploadElement, {
			flashUrl: rootUrl + 'swf/swfupload.swf',
			postParams: {
				offerId: offerId,
				'session_id': $.cookie('PHPSESSID')
			},
			url: rootUrl + 'materialUpload.php',
			fileQueue: $.proxy(this.fileQueue, this),
			fileUploadSuccess: $.proxy(this.fileUploadSuccess, this),
			uploadStart: $.proxy(this.uploadStart, this),
			fileUploadProgress: $.proxy(this.fileUploadProgress, this),
			flashLoaded: $.proxy(this.flashLoaded, this)
		});
		
	},
	insertCartItemHtml: function (item) {
		if (!item.varArray.placeholder) {
			// jos cartissa ei vielä yhtään itemiä
			if (this.itemCount == 0) {
				// poistetaan tyhjän teksti
				this.imgContainer.empty();
			}
			this.imgContainer.append(item.div);
		}
		this.itemCount++;
	},
	itemDeleteCallback: function (item) {
		/*console.log('itemDeleteCallback', item);*/
		this.removeItem(item);
		
		var activated = false;
		$.each(this.items, function () {
			/*console.log('itemDeleteCallback', 'activating item', this);*/
			this.activate();
			activated = true;
			return false;
		});
		if (!activated) {
			/*console.log('itemDeleteCallback', 'no more items!');*/
			this.activeItem = null;
			if (this.options.previewArea != null) {
				this.options.previewArea.removeItem();
			}
		}
		this.updateOfferInfo();
	},
	materialClick: function(e) {
		if (this.activeItem == null) {
			e.preventDefault();
			$('<div><p>' + i18n.noPictures + '</p></div>').dialog({
				modal: true,
				title: 'Info',
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
					}
				}
			});
		}
	},
	orderClick: function (e) {
		e.preventDefault();
		this.orderButton.removeClass('ui-state-focus');
		var images = false;
		$.each(this.items, function () {
			if (!this.varArray.placeholder) {
				images = true;
				return false;
			}
		});
		if (images) {
			new CheckoutDialog();
		}
		else {
			$('<div><p>' + i18n.noPictures + '.<br/>' + i18n.addAtleastOnePicture + '.</p></div>').dialog({
				modal: true,
				title: 'Info',
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
					}
				}
			});
		}
	},
	previewClick: function (e) {
		e.preventDefault();
		this.previewElement.removeClass('ui-state-hover');
		this.previewElement.removeClass('ui-state-active');
		this.previewElement.removeClass('ui-state-focus');
		if (this.activeItem != null && !this.activeItem.varArray.placeholder) {
			new PreviewDialog(this.activeItem);
		}
		else {
			$('<div><p>' + i18n.noPictures + '</p></div>').dialog({
				modal: true,
				title: 'Info',
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
					}
				}
			});
		}
	},
	removeItem: function (item) {
		var newItems = {}
		this.itemCount = 0;
		var self = this;
		$.each(this.items, function () {
			// tässä this viittaa each loopin keyhyn
			if (item.varArray.id != this.varArray.id) {
				newItems[this.varArray.id] = this;
				self.itemCount++;
			}
		});
		this.items = newItems;
	},
	selectElements: function () {
		this.uploadElement = $('#uploadButton');
		this.previewElement = $('#previewButton');
		this.imgContainer = this.element.find('.images');
		this.offerInfoElement = $('#offerInfo');
		this.materialButton = $('.materialProperties');
		this.orderButton = $('.toCart');
	},
	setCountChooser: function (c) {
		this.options.countChooser = c;
		$.each(this.items, function () {
			this.options.priceUpdateCallback = $.proxy(c.updateCurrentPrice, c);
		});
	},
	setStans: function (custom, stans) {
		$.getJSON(
			rootUrl + 'getStans.php',
			{custom: custom, stans: stans},
			$.proxy(this.stansLoadCallback, this)
		);
	},
	stansLoadCallback: function(data) {
		/*console.log('Cart', 'stansLoadCallback', data);*/
		if (this.activeItem != null) {
			this.activeItem.setStans(data);
		}
		if (this.options.previewArea != null) {
			this.options.previewArea.setStans(data);
		}
		if (this.options.countChooser != null) {
			this.options.countChooser.updatePrices();
		}
		// asetetaan stanssi uploaderiin
		if (this.flashIsLoaded) {
			/*console.log('Cart', 'stansLoadCallback', 'setting stans to uploader:', data.id);*/
			this.uploader.getInstance().addPostParam('stansId', data.id);
		}
		/*console.log('Cart', 'stansLoadCallback', 'this.setStansId', data.id);*/
		this.setStansId = data.id;
	},
	updateOfferInfo: function() {
		var html = '<h3>' + i18n.cartInfoHeading + '</h3>';
		if (this.itemCount > 0) {
			html += '<table>';
			
			html += '<tr>';
			html += '<th>';
			html += i18n.cartInfoFile;
			html += '</th>';
			html += '<td>';
			html += this.activeItem.varArray.orig_name;
			html += '</td>';
			html += '</tr>';
			
			html += '<tr>';
			html += '<th>';
			html += i18n.cartInfoStans;
			html += '</th>';
			html += '<td>';
			html += this.activeItem.varArray.stans.description;
			html += '</td>';
			html += '</tr>';
			
			html += '<tr>';
			html += '<th>';
			html += i18n.cartInfoMaterial;
			html += '</th>';
			html += '<td>';
			if (this.activeItem.varArray.material != null) {
				html += this.activeItem.varArray.material.material + ' - ' + this.activeItem.varArray.material.glue;
			}
			html += '</td>';
			html += '</tr>';
			
			html += '<tr>';
			html += '<th>';
			html += i18n.cartInfoFinish;
			html += '</th>';
			html += '<td>';
			if (this.activeItem.varArray.finish != null) {
				html += this.activeItem.varArray.finish.name;
			}
			html += '</td>';
			html += '</tr>';
			
			html += '<tr>';
			html += '<th>';
			html += i18n.cartInfoFormat;
			html += '</th>';
			html += '<td>';
			if (this.activeItem.varArray.format == 0) {
				html += i18n.cartInfoRoll + ' ' + this.activeItem.varArray.shell.name + ' ' + i18n.cartInfoShell;
			}
			else {
				var x = 0;
				var y = 0;
				if (this.activeItem.varArray.per_sheet == 1) {
					x = 1;
					y = 1;
				}
				else {
					x = this.activeItem.varArray.stans.fit_on_sheet;
					y = this.activeItem.varArray.per_sheet / this.activeItem.varArray.stans.fit_on_sheet;
				}
				var size = Math.round(((this.activeItem.varArray.stans.width + this.activeItem.varArray.stans.margin_x) * x * 100)/100) +
						"mm x " + 
							Math.round((this.activeItem.varArray.stans.height + this.activeItem.varArray.stans.margin_y) * y * 100)/100 + "mm<br />";
				html += this.activeItem.varArray.per_sheet + ' / ' + i18n.cartInfoSheet + ', ' + size;
			}
			html += '</td>';
			html += '</tr>';
			
			html += '</table>';
		}
		this.offerInfoElement.html(html);
	},
	uploadStart: function(file) {
		this.uploadingFiles[file.id].uploadStart();
	},
	uploadSuccess: function (item) {
		if (this.activeItem == null || this.activeItem.varArray.placeholder) {
			item.activate();
		}
	}
});

var CartItem = $.klass({
	initialize: function (varArray, options) {
		this.varArray = varArray;
		this.options = {
			activateCallback: function() {},
			initHtmlCallback: function() {},
			uploadSuccess: function() {},
			deleteCallback: function() {},
			reloadCallback: function () {},
			startPriceMethod: function () {return 150;},
			priceUpdateCallback: function () {console.log('priceUpdateCallback stub');},
			updateOfferInfo: function () {}
		}
		$.extend(this.options, options);
		
		this.stans = null;
		//if (!this.varArray.placeholder) {
			if (this.varArray.state == 'upload') {
				this.queue();
			}
			else {
				this.div = $('<div class="img" />');
				this.initHtml();
			}
			this.options.initHtmlCallback(this);
		//}
		this.randomPart = '&r=' + Math.random();
	},
	activate: function () {
		this.div.css({'background-color': '#717070'});
		this.options.activateCallback(this);
	},
	bindEvents: function () {
		this.div.click($.proxy(this.activate, this));
	},
	deactivate: function () {
		this.div.css({'background-color': 'transparent'});
	},
	remove: function () {
		$.getJSON(
			rootUrl + 'itemDelete.php?',
			{id: this.varArray.id},
			$.proxy(this.removeCallback, this)
		);
	},
	removeCallback: function (data) {
		/*console.log('CartItem', 'removeCallback', data);*/
		this.div.remove();
		this.options.deleteCallback(this);
	},
	getPreviewImgUrl: function () {
		return rootUrl + 'thumbnail.php?size=310&id=' + this.varArray.id + '' +  this.randomPart;
	},
	getPrice: function (count) {
		var price = this.options.startPriceMethod();
		var runMeters = this.getRunMeters(count);
		if (runMeters < basePriceChange) {
			price += basePrice1 + this.getMeterPrice1() * runMeters;
		}
		else {
			price += basePrice2 + this.getMeterPrice2() * runMeters;
		}
		return Math.round(price * 100) / 100;
	},
	getCropPreviewUrl: function () {
		return rootUrl + 'previewImage.php?order=' + this.varArray.id + '&orig=1&size=400&bg=white';
	},
	getRunMeters: function (count) {
		var netRunMeters = count / this.getRunDivider();
		return netRunMeters * wasteMultiplier + installWaste;
	},
	getRunDivider: function () {
		var yDivider = this.varArray.stans.height + this.varArray.stans.margin_y;
		var xShift = this.varArray.stans.width + this.varArray.stans.margin_x;
		var xFit = Math.floor(materialWidth / xShift);
		return xFit * yDivider;
	},
	getMeterPrice1: function () {
		return this.varArray.finish.price + this.varArray.material.price;
	},
	getMeterPrice2: function () {
		return this.varArray.finish.price + this.varArray.material.price2;
	},
	initHtml: function () {
		this.img = $('<table><tr><td><img src="' + rootUrl + 'thumbnail.php?size=86&id=' + this.varArray.id +'" /></td></tr></table>');
		
		this.div.append(this.img);
		this.div.css({cursor: 'pointer'});
		this.bindEvents();
	},
	queue: function() {
		this.div = $('<div class="img">' + i18n.cartQueueFile + '<br /><small>' + this.varArray.uploadingFile.name + '</small><br />' + i18n.cartQueueWaiting + '</div>');
	},
	refreshPreview: function () {
		this.randomPart = '&r=' + Math.random();
		this.options.reloadCallback();
		
		this.img.remove();
		
		this.img = $('<table><tr><td><img src="' + rootUrl + 'thumbnail.php?size=86&id=' + this.varArray.id +'&r=' + this.randomPart + '" /></td></tr></table>');
		
		this.div.append(this.img);
	},
	/**
	 * Asettaa ostoskori-itemille stanssin. Stans chooser kutsuu tätä.
	 * @param boolean custom true = omilla mitoilla, false = valittu stanssi
	 * @param mixed joko stanssi id tai mitat ja muoto
	 */
	setStans: function (stans) {
		this.varArray.stans = stans;
		$.post(
			rootUrl + 'stansSet.php',
			{order: this.varArray.id, stans: this.varArray.stans.id},
			$.proxy(this.stansSetCallback, this),
			'json'
		);
	},
	setCrop: function (x, y, w, h, callback) {
		this.options.cropSetCallback = callback;
		$.getJSON(
			rootUrl + "muokkaaTilaus/kuvaRajaaja/" + this.varArray.id,
			{
				x: x,
				y: y,
				w: w,
				h: h
			},
			$.proxy(this.setCropCallback, this));
	},
	setCropCallback: function (data) {
		this.varArray = data.varArray;
		this.options.cropSetCallback(data);
	},
	setCount: function (count) {
		if (count != this.varArray.count) {
			$.getJSON(
				rootUrl + "setCount.php",
				{
					order: this.varArray.id,
					count: count
				},
				$.proxy(this.setCountCallback, this)
			);
		}
	},
	setCountCallback: function (data) {
		if (data.success) {
			this.varArray = data.order;
		}
		else {
			alert(data.error);
		}
	},
	stansSetCallback: function (data) {
		this.varArray = data;
		this.options.priceUpdateCallback();
		this.refreshPreview();
		this.options.updateOfferInfo();
	},
	uploadProgress: function(bytes, total) {
		this.progressbar.progressbar({ value: (bytes / total) * 100 });
	},
	uploadStart: function() {
		// Tyhjennetään odotusteksti
		this.div.empty();
		
		this.div.append(i18n.cartQueueFile + '<br /><small>' + this.varArray.uploadingFile.name + '</small><br />' + i18n.cartQueueSending);
		this.progressbar = $('<div />');
		this.progressbar.progressbar({ value: 0 });
		
		this.div.append(this.progressbar);
	},
	uploadSuccess: function (data) {
		/*console.log('CartItem', 'uploadSuccess', data);*/
		// Poistetaan progressbar & lähetysteksti
		this.div.empty();
		
		this.varArray = data;
		this.varArray.stans = this.stans;
		
		this.initHtml();
		
		this.options.uploadSuccess(this);
	}
});
var CountChooser = $.klass({
	initialize: function(element, cartItem, options) {
		this.element = element;
		this.cartItem = cartItem;
		this.options = {
			saveTimeout: 500
		}
		$.extend(this.options, options);
		
		this.updateTimer = null;
		
		this.selectElements();
		this.updatePrices();
		this.bindEvents();
		return this;
	},
	bindEvents: function () {
		this.button100.click($.proxy(this.button100Click, this));
		this.button500.click($.proxy(this.button500Click, this));
		this.button5000.click($.proxy(this.button5000Click, this));
		this.countInput.keyup($.proxy(this.inputKeyup, this));
	},
	buttonClick: function (count, e) {
		e.preventDefault();
		this.countInput.val(count);
		this.updateCurrentPrice();
	},
	button100Click: function (e) {
		this.buttonClick(100, e);
	},
	button500Click: function (e) {
		this.buttonClick(500, e);
	},
	button5000Click: function (e) {
		this.buttonClick(5000, e);
	},
	inputKeyup: function () {
		if (this.updateTimer != null) {
			
			clearTimeout(this.updateTimer);
		}
		this.updateTimer = setTimeout($.proxy(this.updateCurrentPrice, this), this.options.saveTimeout);
	},
	selectElements: function () {
		this.button100 = this.element.find('.100pcs');
		this.button500 = this.element.find('.500pcs');
		this.button5000 = this.element.find('.5000pcs');
		this.countInput = this.element.find('.countInput');
		this.currentPrice = this.element.find('.currentPrice');
	},
	setCartItem: function (item) {
		this.cartItem = item;
		this.countInput.val(item.varArray.count);
		this.updatePrices();
	},
	updateCurrentPrice: function () {
		var count = parseInt(this.countInput.val());
		if (count > 0 && this.cartItem != null) {
			this.currentPrice.html(this.cartItem.getPrice(count) + ' ');
			this.cartItem.setCount(this.countInput.val());
		}
		
	},
	updatePrices: function (e) {
		if (this.cartItem != null) {
			this.button100.find('span').html('100 ' + i18n.pcs + ' ' + this.cartItem.getPrice(100) + '€');
			this.button500.find('span').html('500 ' + i18n.pcs + ' ' + this.cartItem.getPrice(500) + '€');
			this.button5000.find('span').html('5000 ' + i18n.pcs + ' ' + this.cartItem.getPrice(5000) + '€');
			this.updateCurrentPrice();
		}
	}
});
var SendLinkButton = $.klass({
	initialize: function(element, options) {
		this.options = {
		}
		this.element = element;
		$.extend(this.options, options);

		this.bindEvents();
		return this;
	},
	bindEvents: function () {
		this.element.click($.proxy(this.click, this));
	},
	click: function (e) {
		e.preventDefault();
		this.element.removeClass('ui-state-focus');
		new SendLinkDialog();
	}
});
var SendLinkDialog = $.klass({
	initialize: function(options) {
		this.options = {
			ajaxUrl: rootUrl + 'emailOffer.php',
			location: absoluteRoot + 'muokkaaTilaus/' + cart.share_url
		}
		$.extend(this.options, options);
		this.initHtml();
		return this;
	},
	initHtml: function() {
		this.element = $('<div class="feedback"/>');
		this.form = $('<form method="post"> \
				<p>' + i18n.sendLinkDesc + '</p> \
				<p><strong>' + i18n.sendLinkRecipent + '</strong><br/> \
				<input style="width: 200px" name="recipent" type="text"></p> \
				<p><strong>' + i18n.sendLinkTitle + '</strong><br/> \
				<input style="width: 200px" name="subject" type="text" value="' + i18n.sendLinkTitleDefault + '"></p> \
				<p><strong>' + i18n.sendLinkSender + '</strong><br/> \
				<input style="width: 200px" name="from" type="text" value="' + (cart.owner ? cart.owner.email : '') + '"></p> \
				<p><strong>' + i18n.sendLinkMessage + '</strong><br/> \
				<textarea style="width: 360px; height: 150px;" name="message">' + i18n.sendLinkMessageDefault + '\n' + this.options.location + '</textarea>\
				<input type="hidden" name="offer" value="' + cart.id + '" /></p> \
			</form>');
		this.element.append(this.form);
		this.element.dialog({
			width: 400,
			height: 535,
			modal: true,
			buttons: [
				{
					text: i18n.feedbackCancel,
					click: $.proxy(this.cancel, this)
				},
				{
					text: i18n.feedbackSend,
					click: $.proxy(this.send, this)
				}
			],
			title: i18n.sendLinkDialogTitle
		});
		this.element.find('[name="recipent"]').focus();
	},
	cancel: function () {
		this.element.dialog( "close" );
		this.element.dialog( "destroy" );
		this.element.remove();
	},
	send: function () {
		$.post(
			this.options.ajaxUrl,
			this.form.serializeArray(),
			$.proxy(this.sentCallback, this),
			'json'
		);
	},
	sentCallback: function (data) {
		if (data.success) {
			this.element.dialog( "close" );
			this.element.dialog( "destroy" );
			this.element.remove();
			$('<div><p>' + i18n.sendLinkDone + '</p></div>').dialog({
				modal: true,
				title: sendLinkDoneTitle,
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
						$( this ).remove();
					}
				}
			});
		}
		else {
			$('<div><p>' + i18n.sendLinkErrorSending + '<br/>' + data.error +'</p></div>').dialog({
				modal: true,
				title: i18n.sendLinkError,
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
						$( this ).remove();
					}
				}
			});
		}
	}
});
var TellFriendButton = $.klass({
	initialize: function(element, options) {
		this.options = {
		}
		this.element = element;
		$.extend(this.options, options);

		this.bindEvents();
		return this;
	},
	bindEvents: function () {
		this.element.click($.proxy(this.click, this));
	},
	click: function (e) {
		e.preventDefault();
		this.element.removeClass('ui-state-focus');
		new TellFriendDialog();
	}
});
var TellFriendDialog  = $.klass({
	initialize: function(options) {
		this.options = {
			ajaxUrl: rootUrl + 'emailFriend.php'
		}
		$.extend(this.options, options);
		this.initHtml();
		return this;
	},
	initHtml: function() {
		this.element = $('<div class="feedback"/>');
		this.form = $('<form method="post"> \
				<p>' + i18n.tellFriendDesc + '</p> \
				<p><strong>' + i18n.tellFriendRecipent + '</strong><br/> \
				<input style="width: 200px" name="recipent" type="text"></p> \
				<p><strong>' + i18n.tellFriendSender + '</strong><br/> \
				<input style="width: 200px" name="from" type="text" value="' + (cart.owner ? cart.owner.email : '') + '"></p> \
				<p><strong>' + i18n.tellFriendGreeting + '</strong><br/> \
				<textarea style="width: 360px; height: 100px;" name="message"></textarea>\
				<p><strong>' + i18n.tellFriendAttachementDesc + '</strong><br/> \
				' + i18n.tellFriendAttachement + '</p> \
				<input type="hidden" name="offer" value="' + cart.id + '" /></p> \
			</form>');
		this.element.append(this.form);
		this.element.dialog({
			width: 500,
			height: 560,
			modal: true,
			buttons: [
				{
					text: i18n.feedbackCancel,
					click: $.proxy(this.cancel, this)
				},
				{
					text: i18n.feedbackSend,
					click: $.proxy(this.send, this)
				}
			],
			title: i18n.tellFriendTitle
		});
		this.element.find('[name="recipent"]').focus();
	},
	cancel: function () {
		this.element.dialog( "close" );
		this.element.dialog( "destroy" );
		this.element.remove();
	},
	send: function () {
		$.post(
			this.options.ajaxUrl,
			this.form.serializeArray(),
			$.proxy(this.sentCallback, this),
			'json'
		);
	},
	sentCallback: function (data) {
		if (data.success) {
			this.element.dialog( "close" );
			this.element.dialog( "destroy" );
			this.element.remove();
			$('<div><p>' + i18n.tellFriendSent + '</p></div>').dialog({
				modal: true,
				title: i18n.tellFriendSentTitle,
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
						$( this ).remove();
					}
				}
			});
		}
		else {
			$('<div><p>' + i18n.tellFriendError + '<br/>' + data.error +'</p></div>').dialog({
				modal: true,
				title: i18n.tellFriendErrorTitle,
				buttons: {
					'Ok': function() {
						$( this ).dialog( "close" );
						$( this ).dialog( "destroy" );
						$( this ).remove();
					}
				}
			});
		}
	}
});
var InfoLink = $.klass({
	initialize: function(element, options) {
		this.options = {
		}
		this.element = element;
		$.extend(this.options, options);
		this.opened = false;
		this.inited = false;
		
		this.selectElements();
		this.bindEvents();
		return this;
	},
	bindEvents: function () {
		this.toggleButton.click($.proxy(this.toggleClick, this));
	},
	close: function () {
		this.infoContent.dialog('close');
		this.opened = false;
	},
	open: function () {
		var offset = this.element.offset();
		this.infoContent.dialog({
			title: 'Info',
			show: 'blind',
			position: [
				offset.left + this.element.width() / 2 - 150,
				offset.top + this.element.height() - $('html').scrollTop()
			],
			width: '300px'
		});
		this.inited = true;
		this.infoContent.dialog('open');
		this.opened = true;
	},
	toggleClick: function (e) {
		e.preventDefault();
		if (this.opened) {
			this.close();
		}
		else {
			this.open();
		}
	},
	selectElements: function () {
		this.toggleButton = this.element.find('.infoToggle');
		this.infoContent = this.element.find('.infoContent');
	}
});
var MultiUpload = $.klass({
	initialize: function(element, options) {
		this.element = element;
		this.options = {
			// options
			flashUrl: 'swfupload.swf',
			postParams: {},
			url: 'upload.php',
			rules: {
				'image' : {
					'fileTypes' : ['jpeg', 'jpg', 'png', 'tiff', 'tif', 'psd', 'pdf'],
					'limit' : 6
				}
			},
			fileTypesDescription: i18n.uploadFileDesc,
			// events
			buttonMouseOver: function () {},
			buttonMouseOut: function () {},
			buttonMouseClick: function () {},
			fileDialogComplete: $.proxy(this.startUpload, this),
			fileQueue: function(file) {
				/*console.log('fileQueue', file);*/
			},
			fileUploadError: function(file,data,response){
				/*console.log('fileUploadError', file, data, response);*/
			},
			fileUploadSuccess: function(file,data,response){
				/*console.log('fileUploadSuccess', file, data, response);*/
			},
			fileUploadProgress: function(file, bytes, total) {
				/*console.log('fileUploadProgress', file, bytes, total);*/
			},
			flashLoaded: function () {},
			uploadComplete: function(data) {},
			uploadStart: function(file) {
				/*console.log('uploadStart', file);*/
			}
			
		};
		$.extend(this.options, options);
		this.uploadContainer = $('<div />');
		this.element.parent().css({
			position: 'relative',
			'float': 'left'
		});
		this.uploadContainer.css({
			position: 'absolute',
			top: '0',
			left: '0',
			height: Math.ceil(this.element.height() + 1) + 'px',
			width: Math.ceil(this.element.width() + 1) + 'px'
		});
		
		// lisätään flash container domiin
		this.element.after(this.uploadContainer);
		this.jqswfu = this.uploadContainer.jqswfupload({
			buttonHeight: Math.ceil(this.element.height() + 1),
			buttonImageUrl: '',
			buttonMouseOver: $.proxy(this.buttonMouseOver, this),
			buttonMouseOut: $.proxy(this.buttonMouseOut, this),
			buttonMouseClick: $.proxy(this.buttonMouseClick, this),
			buttonWidth: Math.ceil(this.element.width() + 1),
			buttonWmode: 'transparent',
			buttonText: '',
			buttonTextTopPadding: 0,
			fileTypesDescription: this.options.fileTypesDescription,
			
			flashUrl: this.options.flashUrl,
			
			flashLoaded: this.options.flashLoaded,
			fileDialogComplete: this.options.fileDialogComplete,
			fileQueue: this.options.fileQueue,
			fileUploadProgress: this.options.fileUploadProgress,
			fileUploadSuccess: this.options.fileUploadSuccess,
			fileUploadError: this.options.fileUploadError,
			
			rules: this.options.rules,
			
			uploadComplete: this.options.uploadComplete,
			uploadStart: this.options.uploadStart,
			url: this.options.url,
			
			postParams: this.options.postParams
		});
		this.element.click(function(e) {
			e.preventDefault();
			$('<p>' + i18n.uploadFlashNeeded + '</p>').dialog({
				height: 240,
				width: 400,
				title: i18n.error,
				buttons: [
					{
						text: i18n.uploadInstallFlash,
						click: function() {
							window.location = 'http://get.adobe.com/flashplayer/';
						}
					},
					{
						text: i18n.cancel,
						click: function() {
							$( this ).dialog( "close" );
						}
					}
				]
			});
		});
	},
	setPostParams: function (params) {
		var swfu = this.getInstance();
		swfu.addPostParam('cart_product_id', params.cart_product_id);
	},
	buttonMouseClick: function () {
		this.element.addClass('ui-state-active');
		this.options.buttonMouseClick();
	},
	buttonMouseOver: function () {
		this.element.addClass('ui-state-hover');
		this.options.buttonMouseOver();
	},
	buttonMouseOut: function () {
		this.element.removeClass('ui-state-hover');
		this.element.removeClass('ui-state-active');
		this.options.buttonMouseOut();
	},
	getInstance: function () {
		return this.uploadContainer.jqswfupload('getInstance');
	},
	startUpload: function () {
		this.uploadContainer.jqswfupload('startUpload');
	}
});
