// We had differnt Problems in the Past, where Orders have been created multiple times
// Therefor we introduce a global Trigger here, which stops the Class from creating multiple Orders !
var GetTanHasBeenTriggered = false;
var OpenOrderHasBeenTriggered = false;

function LIS() {
}
LIS.prototype = {
	priority: 0,
	id: 0,
	url: "",

	host: "",
	port: 0,
	scheme: "",
	path: "",
	
	parse: function() {
		if(this.url == "") {
			return false;
		}
		
		var regexp = /(http[s]?:\/\/)([^\/]+)/i;
		
		regexp.exec(this.url);
		this.scheme = RegExp.$1;
		this.host = RegExp.$2;
		
		var hasPort = this.host.split(":");
		if(hasPort.length == 2) {
			this.host = hasPort[0];
			this.port = hasPort[1];
		} else {
			this.port = 80;
		}
	},
	
	getUploadUrl: function() {
		return this.scheme + this.host + ":" + this.port + this.path;
	}
}

function BackBone4(vendorid) {
	this.vendorid = vendorid;
	this.http = new HTTP();
}

BackBone4.prototype = {
	proxy: window.location.protocol + "//" + window.location.hostname + "/proxy/proxy.php",
	vendorid: false,
	http: false,
	LIS: new LIS(),
	
	tan: false,
	orderid: false,
	
	fileCount: false,
	
	progress: {
		LisRetrieved: false,
		TanRetrieved: false,

		UploadStarted: false,
		UploadFinished: false,
		UploadFailed: false,
		UploadCanceled: false,

		OrderOpened: false,
		OrderConfirmed: false,
		OrderCanceled: false,
		OrderFailed: false,
		
		OpeningOrder: false
	},
	
	resetProgress: function() {
		this.progress = {
			LisRetrieved: false,
			TanRetrieved: false,

			UploadStarted: false,
			UploadFinished: false,
			UploadFailed: false,
			UploadCanceled: false,
	
			OrderOpened: false,
			OrderConfirmed: false,
			OrderCanceled: false,
			OrderFailed: false,
		
			OpeningOrder: false
		}
	},
	
	send: function(service, XML, respObj) {
		this.http.post(this.proxy + "?service=" + encodeURI(service) + "&XML=" + encodeURI(XML) + "&vendorid=" + this.vendorid, respObj);
	},
	
	getLis: function(fileCount, uploadSize, orderInfos) {
		this.addStatusMessage(41100);
		this.setStatus(1);
		
		this.fileCount = fileCount;

		if(orderInfos[0] && orderInfos[1]) {
			this.tan = orderInfos[0];
			this.orderid = orderInfos[1];
		}
		
		var XML = '<?xml version="1.0"?>\
		<DATA>\
			<VENDORID>' + this.vendorid + '</VENDORID>\
			<FILES>' + fileCount + '</FILES>\
			<KILOBYTE>' + (uploadSize || '') + '</KILOBYTE>\
		</DATA>';

		this.send("/updates/getLIS.cgi", XML, new Response(function() {
			var bb4 = this.parent;

			var servers = this.getXml().getElementsByTagName("SERVER");
			for(var i = 0; i < servers.length; i++) {
				if(findNode(servers[i], "PRIORITY").nodeValue > bb4.LIS.priority) {
					bb4.LIS.priority = findNode(servers[i], "PRIORITY").nodeValue,
					bb4.LIS.id = findNode(servers[i], "ID").nodeValue,
					bb4.LIS.url = findNode(servers[i], "URL").nodeValue
				}
			}

			bb4.LIS.parse();
			bb4.send(bb4.LIS.url, "", new Response(function() {
				var data = this.getXml().getElementsByTagName("DATA")[0];
				bb4.LIS.path = findNode(data, "PATH").nodeValue + "/" + findNode(findNode(data, "SCRIPTS"), "UPLOAD").nodeValue;

				if(bb4.progress.OrderCanceled == false) {
					if(bb4.tan && bb4.orderid) {
						bb4.stopInterval("GetTan");
						bb4.stopInterval("OpenOrder");
						
						bb4.progress.LisRetrieved = true;
						bb4.progress.TanRetrieved = true;
						bb4.progress.OrderOpened = true;
					} else {
						bb4.progress.LisRetrieved = true;
					}
				} else {
					bb4.progress.OrderCanceled = false;
				}				
			}, false, bb4));
		}, false, this));
	},
	
	getTan: function() {
		var getTanInterval = new StandardInterval("GetTan", this, function() {
			var bb4 = this.parent;
			if(bb4.progress.LisRetrieved == false) {
				return false;
			}
			
			if(GetTanHasBeenTriggered == true) {
				try {
					this.stop();
				} catch(e) {
				}
				return false;
			}
			
			GetTanHasBeenTriggered = true;

			this.stop();

			bb4.addStatusMessage(41101);
			bb4.setStatus(2);
			
			var XML = '<?xml version="1.0"?>\
			<DATA>\
				<VENDORID>' + bb4.vendorid + '</VENDORID>\
				<TARGET>shop</TARGET>\
			</DATA>';
			
			bb4.send("/order/getTAN.cgi", XML, new Response(function() {
				var data = this.getXml().getElementsByTagName("DATA")[0];
				var info = findNode(data, "ORDER");
			
				bb4.tan = findNode(info, "TAN").nodeValue;
				bb4.orderid = findNode(info, "ORDERID").nodeValue;

				bb4.progress.TanRetrieved = true;
			}));
		});
		
		this.appendInterval(getTanInterval.interval, function() {
			getTanInterval.callback();
		});
	},
	
	openOrder: function(email, lang, clienttype, version, sid) {
		clienttype = clienttype || 4;
		version = version || "1.0";
		sid = sid || "1.0";
		
		var openOrderInterval = new StandardInterval("OpenOrder", this, function() {
			var bb4 = this.parent;
			if(bb4.progress.TanRetrieved == false) {
				return false;
			}
			
			if(OpenOrderHasBeenTriggered == true) {
				try {
					this.stop();
				} catch(e) {
				}
				return false;
			}
			
			OpenOrderHasBeenTriggered = true;

			this.stop();
			
			var XML = '<?xml version="1.0"?>\
			<DATA>\
				<VENDORID>' + bb4.vendorid + '</VENDORID>\
				<ORDER>\
					<TAN>' + bb4.tan + '</TAN>\
					<ORDERID>' + bb4.orderid + '</ORDERID>\
				</ORDER>\
				<CLIENT>\
					<VERSION>' + version + '</VERSION>\
					<CLIENTTYPE>' + clienttype + '</CLIENTTYPE>\
					<LANG>' + lang + '</LANG>\
					<ENGINE>' + sid + '</ENGINE>\
				</CLIENT>\
				<CUSTOMER>\
					<EMAIL>' + email + '</EMAIL>\
				</CUSTOMER>\
			</DATA>';
			
			bb4.progress.OpeningOrder = true;
			bb4.send("/order/openOrder.cgi", XML, new Response(function() {
				bb4.progress.OrderOpened = true;
				bb4.progress.OpeningOrder = false;
			}));
		});
		
		this.appendInterval(openOrderInterval.interval, function() {
			openOrderInterval.callback();
		});
	},
	
	confirmOrder: function() {
		var confirmOrderInterval = new StandardInterval("ConfirmOrder", this, function() {
			var bb4 = this.parent;
			if(bb4.progress.UploadFinished == false) {
				return false;
			}

			this.stop();			
			bb4.stopInterval("UploadCancel");
			bb4.stopInterval("UploadFailure");

			bb4.addStatusMessage(41103);
			bb4.setStatus(bb4.fileCount + 4);
			
			var XML = '<?xml version="1.0"?>\
			<DATA>\
				<VENDORID>' + bb4.vendorid + '</VENDORID>\
				<ORDER>\
					<TAN>' + bb4.tan + '</TAN>\
					<ORDERID>' + bb4.orderid + '</ORDERID>\
					<COMPLETE>0</COMPLETE>\
				</ORDER>\
			</DATA>';
			
			bb4.send("/order/confirmOrder.cgi", XML, new Response(function() {
				bb4.progress.OrderConfirmed = true;
			}));
		});
		
		this.appendInterval(confirmOrderInterval.interval, function() {
			confirmOrderInterval.callback();
		});
	},
	
	listenForUploadFailure: function() {
		var listenForUploadFailureInterval = new StandardInterval("UploadFailure", this, function() {
			var bb4 = this.parent;
			
			if(bb4.progress.UploadFailed == false) {
				return false;
			}

			bb4.stopAllIntervals();

			bb4.addStatusMessage(437);
			
			var XML = '<?xml version="1.0"?>\
			<DATA>\
				<VENDORID>' + bb4.vendorid + '</VENDORID>\
				<ORDER>\
					<TAN>' + bb4.tan + '</TAN>\
					<ORDERID>' + bb4.orderid + '</ORDERID>\
				</ORDER>\
			</DATA>';
			
			if(window.IsPopupUploader && IsPopupUploader()) {
				bb4.resetProgress();
				bb4.progress.OrderFailed = true;
			} else {
				bb4.send("/order/failureOrder.cgi", XML, new Response(function() {
					bb4.progress.OrderFailed = true;
				}));
				bb4.resetProgress();
			}
		});
		
		this.appendInterval(listenForUploadFailureInterval.interval, function() {
			listenForUploadFailureInterval.callback();
		});
	},
	
	listenForUploadCancel: function() {
		var listenForUploadCancelInterval = new StandardInterval("UploadCancel", this, function() {
			var bb4 = this.parent;
			
			if(bb4.progress.UploadCanceled == false) {
				return false;
			}

			bb4.stopAllIntervals();

			bb4.addStatusMessage(430);
			
			var XML = '<?xml version="1.0"?>\
			<DATA>\
				<VENDORID>' + bb4.vendorid + '</VENDORID>\
				<ORDER>\
					<TAN>' + bb4.tan + '</TAN>\
					<ORDERID>' + bb4.orderid + '</ORDERID>\
				</ORDER>\
			</DATA>';
			
			if(window.IsPopupUploader && IsPopupUploader()) {
				bb4.progress.OrderCanceled = true;
				bb4.resetProgress();
			} else {
				bb4.send("/order/cancelOrder.cgi", XML, new Response(function() {
					bb4.progress.OrderCanceled = true;
				}));				
				bb4.resetProgress();
			}
		});
		
		this.appendInterval(listenForUploadCancelInterval.interval, function() {
			listenForUploadCancelInterval.callback();
		});
	},
	
	listenForPageReload: function() {
		var listenForPageReloadInterval = new StandardInterval("PageReload", this, function() {
			var bb4 = this.parent;
			
			if(bb4.progress.OrderCanceled == false && bb4.progress.OrderFailed == false) {
				return false;
			}

			this.stop();
			window.location.reload();
		});
		
		this.appendInterval(listenForPageReloadInterval.interval, function() {
			listenForPageReloadInterval.callback();
		});
	},
	
	
	intervalList: [],
	appendInterval: function(name, callback) {
		this.intervalList[name] = setInterval(callback, 500);
	},		
	stopInterval: function(name) {
		clearInterval(this.intervalList[name]);
	},
	stopAllIntervals: function() {
		for(key in this.intervalList) {
			if(key != "PageReload") {
				clearInterval(this.intervalList[key]);
			}
		}	
	},
	
	lblStatusMessage: false,
	resetStatusMessage: function() {
		this.addStatusMessage(false, true);
	},
	addStatusMessage: function(statusMessage, reset) {
		if(this.lblStatusMessage == "notfound") {
			return false;
		}

		if(isNaN(statusMessage) == false) {
			statusMessage = getString(statusMessage); 
		}
		
		if(this.lblStatusMessage == false) {
			this.lblStatusMessage = document.getElementById("StatusMessage");
			if(!this.lblStatusMessage) {
				this.lblStatusMessage = "notfound";
				return false;
			}
			
			this.lblStatusMessage.style.display = "block";
		}

		if(reset == true) {
			while(this.lblStatusMessage.hasChildNodes()) {
				this.lblStatusMessage.removeChild(this.lblStatusMessage.firstChild);
			}
		} else {
			var init = !this.lblStatusMessage.hasChildNodes();
			if(init == false) {
				this.lblStatusMessage.appendChild(document.createElement("br"));
			}
			this.lblStatusMessage.appendChild(document.createTextNode(statusMessage));
		}
		
		this.lblStatusMessage.scrollTop = this.lblStatusMessage.scrollHeight;
	},
	
	lblStatusBar: false,
	statusItemCount: 0,
	setStatusItemCount: function(statusItemCount) {
		this.statusItemCount = statusItemCount;
	},
	setStatus: function(id) {
		if(this.lblStatusBar == "notfound") {
			return false;
		}
		
		if(this.lblStatusBar == false) {
			this.lblStatusBar = document.getElementById("StatusBar");
			if(!this.lblStatusBar) {
				this.lblStatusBar = "notfound";
				return false;
			}
			
			this.lblStatusBar.parentNode.style.display = "block";
		}

		if(id == 0) {
			this.lblStatusBar.parentNode.style.display = "none";
		} else {
			this.lblStatusBar.style.width = Math.round(id * 100 / this.statusItemCount) + "%";
		}
	}
	
}

function StandardInterval(name, parent, callback) {
	this.parent = parent;
	this.interval = name;
	this.callback = callback;
}

StandardInterval.prototype = {
	stop: function() {
		clearInterval(this.parent.intervalList[this.interval]);
	}
}