from browser import bind, window, document, timer;


import sys, os;
import re;
import time
import html;

#import lxml;
#from lxml.html import builder as E;

#def getHTML(e):
#	return lxml.html.tostring(e).decode();

import browser.html as E;

def getHTML(e):
	return e.outerHTML;


from browser.widgets.dialog import Dialog, InfoDialog;

class mainwindow:
	@staticmethod
	def setWindowTitle(title):
		document.title = title;
	
	class _statusBar:
		@staticmethod
		def showMessage(msg):
			document["statusBar"].innerText = msg;
	
	def statusBar(this):
		return this._statusBar;
	
	
	class progressBar:
		@staticmethod
		def show():
			document["progressBar"].style.display = "block";
		@staticmethod
		def hide():
			document["progressBar"].style.display = "none";
		@staticmethod
		def setValue(val):
			document["progressBar"].value = val;
	
	class messages:
		@staticmethod
		def setText(val):
			document.select_one("[name=messages]").innerHTML = val;
		
		def append(val):
			# FIXME
			document.select_one("[name=messages]").innerHTML += val+"<br />";
	
	class scoresBrowser:
		@staticmethod
		def setText(val):
			document.select_one("[name=scoresBrowser]").innerHTML = val;
		
		def append(val):
			# FIXME
			document.select_one("[name=scoresBrowser]").innerHTML += val+"<br />";


from src.functions import *

def colorCodeUsed(text):
	return bool(re.search(REGEX_COLORS, text));

def htmlColor(_str,
	whiteIsRESETT=True,
	colorStyle="background:black",
	darkColorStyle="background:white",
):
	#return re.sub(REGEX_COLORS, r"<font color='#\1'>\2</font>", _str);
	colors = re.findall(REGEX_COLORS, "0xRESETT"+_str);
	out = "";
	for c in colors:
		if( c[0] == "RESETT" or ( whiteIsRESETT and c[0] == "ffffff" ) ):
			out += html.escape(c[1]);
		else:
			cl = int(float.fromhex(c[0]));
			r = (cl&0xff0000) / 0xff0000;
			g = (cl&0x00ff00) / 0x00ff00;
			b = (cl&0x0000ff) / 0x0000ff;
			if( ( r < 0.5 and g < 0.5 and b < 0.5 ) or ( r+g+b < 0.7 ) ):
				style = darkColorStyle;
			else:
				style = colorStyle;
			#rgb"+str((int(r*255),int(g*255),int(b*255)))+"
			#out += "<font color='#"+c[0]+"' style='"+style+"'>"+html.escape(c[1]).replace("  ", " &nbsp;")+"</font>";
			out += "<span style='color:rgb"+str((int(r*255),int(g*255),int(b*255)))+";"+style+"'>"+html.escape(c[1]).replace("  ", " &nbsp;")+"</span>";
	return out;


from common import Worker;

class Main(mainwindow):
	def aarecOpen(this, e=None):
		fileTypes = [
			#"All supported (*.aarec *.zip *.gz)",
			"Armagetron Advanced Recordings (*.aarec)",
			#"Compressed Files (*.zip *.gz)",
			"All Files (*.*)" # should always be last
		];
		
		
		f = document.createElement("input");
		f.type = "file";
		def open_( e ):
			print("load");
			if( e.target.files.length > 0 ):
				print( e.target.files[0] );
				this.aarecLoad( e.target.files[0] );
		f.bind( "change", open_ );
		r = window.FileReader.new();
		f.click();
	
	def clear(this):
		this.worker.message.cbs.clear();
		this.worker.scoreboard.cbs.clear();
		this.worker.scoreRq.cbs.clear();
		this.worker.finished.cbs.clear();
	
	def aarecLoad(this, f):
		if( True ):
			this.setWindowTitle( this.progTitle+" - "+f.name );
			
			this.statusBar().showMessage("Please wait...");
			
			
			# prepare progressbar
			this.progressBar.show();
			
			# prepare message log output
			this.messages.setText("");
			# set color output background depending on color scheme
			def htmlColorCust(msg):
					return htmlColor(msg,colorStyle="");
			this.worker.message.connect(lambda time, msg: this.messages.append("["+str(time)+"] <span>"+htmlColorCust(msg)+"</span>"));
			
			sState = {};
			sState["scoreRq"] = False;
			
			this.scoresBrowser.setText("");
			def appendScoreBoard(data):
				print("hi");
				
				spectators = [];
				
				def TH(*text):
					return E.TH(align="left", *text);
				
				teamScoreBoard = E.TABLE(E.TR( 
					TH("Teamname")+ TH("Score")
				));
				
				playerScoreBoard = E.TABLE(E.TR(
					TH("Player")+ TH("Score")+ TH("Team")
				));
				
				for t in data["teams"]: 
					name = t["name"]; score = str(t["score"]);
					if( t["numPlayers"] <= 0 ):
						name = E.S( t["name"] );
						#score = E.S( score );
					teamScoreBoard.append(E.TR(
						E.TD( name )+ E.TD( score, align="right" )
					));
				
				for p in data["players"]:
					if( p["team"] or p["score"] ):
						if( p["team"] ): team = str(p["team"]);
						elif( p["teamID"] ): team = E.I("error");
						else: team = E.I("spec");
						playerScoreBoard.append(E.TR(
							E.TD(p["name"])+ E.TD(str(p["score"]), align="right")+ E.TD( team )
						));
					else:
						if( p["teamID"] ):
							spectators.append(p["name"]+" (error)");
						else:
							spectators.append(p["name"]);
				
				if( sState["scoreRq"] ):
					sState["scoreRq"] = False;
					this.scoresBrowser.append("");
				
				this.scoresBrowser.append(getHTML(
						E.DIV(
							E.P("Time: "+str(data["time"]))+
							E.P("Winner: "+str(data["winner"]))+
							teamScoreBoard+
							playerScoreBoard+
							E.P("Spectators: "+str.join(", ", spectators)),
						)
					)
				);
				this.scoresBrowser.append("");
			this.worker.scoreboard.connect(appendScoreBoard);
			
			def scoreRq( time, type_, name, score ):
				if( score and type_ != "Team" ):
					this.scoresBrowser.append(getHTML(
						(E.SPAN(
							"[%s] %s %s left with %i points" % (
								str(time), type_, name, score
							), style="line-height:100%"
						))
					));
					sState["scoreRq"] = True;
			
			this.worker.scoreRq.connect(scoreRq);
			
			def onFinish():
				this.progressBar.hide();
				this.clear();
			
			this.worker.finished.connect(onFinish);
			
			# start
			this.worker.loadFile.emit( f );
	
	@staticmethod
	def onFatalError(e):
		print( e, file=sys.stderr );
		
		d = InfoDialog( "Fatal Error", E.PRE( e ) )
		
		#print( d.width );
		def repos():
			d.style.top = str( ( document.body.height / 2 ) - ( d.height / 2 ) )+"px";
			d.style.left = str( ( document.body.width / 2 ) - ( d.width / 2 ) )+"px";
		timer.set_timeout(repos, 0);
	
	def __init__(this):
		super(Main, this).__init__();
		
		this.progTitle = "AAREC-Parser";
		this.setWindowTitle(this.progTitle);
		
		this.worker = Worker();
		this.worker.run();
		
		
		this.progressBar.setValue(0);
		this.progressBar.hide();
		this.worker.progress.connect(this.progressBar.setValue);
		
		this.worker.status.connect(this.statusBar().showMessage);
		
		
		this.worker.fatalError.connect( this.onFatalError );
		
		
		this.statusBar().showMessage("No file loaded.");
		
		document["actionOpen"].bind( "click", this.aarecOpen );
		
		


window.m = Main();



