package jatek0002;

import java.io.File;
import java.io.IOException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import jatek.Jatek;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.Number;

public class Jatek0002 implements Jatek{

private static int tableWidth=500;
	
	private Jatek0002GameData jgd = new Jatek0002GameData();
	private Jatek0002Panel jk0002 = new Jatek0002Panel();
	
	
	@Override
	public void closeGame() {
		jk0002.getGameInputContent().setText("");
		jgd.setToExcel(false);
		jk0002.getGameResults().setText("Eredmények");
		jk0002.setPanel("input");
		jk0002.getGr().setDrawLineA(null);
		jk0002.getGr().setDrawLineB(null);
		jgd.setEquilibriaString(null);
		jgd.setEquilibriaLength(0);
		jk0002.getGr().setEquilibria(null);
		jk0002.getGr().setEquilibriaLength(0);
		jk0002.getGr().repaint();
		
	}

	@Override
	public boolean createSaveDataFormat(File save) {
		if(!jgd.isToExcel()){
			jk0002.showMessage("toExcelProblem");
			return false;
		}
		try {
			WritableWorkbook w = Workbook.createWorkbook(save);
			WritableSheet s = w.createSheet(jgd.getName(), 0);
			s.addCell(new Label(0, 0, "Információk a játékról"));
			s.addCell(new Label(0, 3, "Kód"));s.addCell(new Label(1, 3, jgd.getCode()));
			s.addCell(new Label(0, 5, "Név"));s.addCell(new Label(1, 5, jgd.getName()));
			s.addCell(new Label(0, 7, "Szerző"));s.addCell(new Label(1, 7, jgd.getAuthor()));
			s.addCell(new Label(0, 9, "Dátum"));s.addCell(new Label(1, 9, jgd.getDate()));
			
			//A	
			s.addCell(new Label(0, 11, "A"));
			s.addCell(new Label(1, 11, jgd.getCol1()));
			s.addCell(new Label(2,11, jgd.getCol2()));
			s.addCell(new Label(0,12, jgd.getRow1()));
			s.addCell(new Label(0,13, jgd.getRow2()));
			
			//B
			s.addCell(new Label(4, 11, "B"));
			s.addCell(new Label(5, 11, jgd.getCol1()));
			s.addCell(new Label(6,11, jgd.getCol2()));
			s.addCell(new Label(4,12, jgd.getRow1()));
			s.addCell(new Label(4,13, jgd.getRow2()));
			
			int currCellCol=1;
			int currCellRow=12;
			for(int i=0;i<2;i++){
				for(int j=0;j<2;j++){
					s.addCell(new Number(currCellCol+i, currCellRow+j, jgd.getAdata()[j][i]));
				}
			}
			currCellCol=5;
			for(int i=0;i<2;i++){
				for(int j=0;j<2;j++){
					s.addCell(new Number(currCellCol+i, currCellRow+j, jgd.getAdata()[j][i]));
				}
			}
			s.addCell(new Label(0, 15, "Egyensúlypontok"));s.addCell(new Label(1, 15, jgd.getEquilibriaString()));
			
			w.write();
			w.close();
			
		} catch (WriteException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		} 
		return true;

	}
	
	
	@Override
	public void loadData(Document d) {
		Element root = d.getDocumentElement();
		Element gameElement=null;
		NodeList children=null;
		getLabel(root,gameElement,children,"information");
		getLabel(root,gameElement,children,"name");
		getLabel(root,gameElement,children,"description");
		getLabel(root,gameElement,children,"date");
		getLabel(root,gameElement,children,"col1");
		getLabel(root,gameElement,children,"col2");
		getLabel(root,gameElement,children,"row1");
		getLabel(root,gameElement,children,"row2");
		
		//author
		String author="";
		children = root.getElementsByTagName("author");
		for (int childrenNum = 0; childrenNum < children.getLength(); childrenNum++){
			gameElement = (Element)children.item(childrenNum);
			author+=gameElement.getFirstChild().getNodeValue()+"<br>";
        }
		//inputs
		children = root.getElementsByTagName("Adata");
		gameElement = (Element)children.item(0);
		
		String tempData = gameElement.getFirstChild().getNodeValue();
		tempData = tempData.replace("{", ",");
		tempData = tempData.replace("}", ",");
		
		String[] tempDataArray=tempData.split(",");
		
		int k=0;
		int j=0;
		int rows=2;
		int cols=2;
		Double[][] data= new Double[rows][cols];
		for(int i=0;i<tempDataArray.length;i++){
			try{
				if(k!=cols){
					data[j][k]=Double.parseDouble(tempDataArray[i]);
					k++;
				}else{
					k=0;
					j++;
					data[j][k]=Double.parseDouble(tempDataArray[i]);
				}
			}catch(NumberFormatException e){
				e.getMessage();
			}
		}
		jgd.setAdata(data);
		children = root.getElementsByTagName("Bdata");
		gameElement = (Element)children.item(0);
		
		tempData = gameElement.getFirstChild().getNodeValue();
		tempData = tempData.replace("{", ",");
		tempData = tempData.replace("}", ",");
		
		tempDataArray=tempData.split(",");
		
		k=0;
		j=0;
		rows=2;
		cols=2;
		data= new Double[rows][cols];
		for(int i=0;i<tempDataArray.length;i++){
			try{
				if(k!=cols){
					data[j][k]=Double.parseDouble(tempDataArray[i]);
					k++;
				}else{
					k=0;
					j++;
					data[j][k]=Double.parseDouble(tempDataArray[i]);
				}
			}catch(NumberFormatException e){
				e.getMessage();
			}
		}
		jgd.setBdata(data);
		
		jgd.setAuthor(author);
		
		String[] cls = {jgd.getCol1(),jgd.getCol2()};
		String[] rws = {jgd.getRow1(),jgd.getRow2()};
		jgd.setGameInputHtmlContent("<html><p>A</p>"+createGameContent(rws,cls,jgd.getAdata(),tableWidth)+"<br><p>B</p>"+createGameContent(rws,cls,jgd.getBdata(),tableWidth)+"</html>");
		jk0002.showMessage("loaded");
	}
	/**
	 * Az xml egy magadott tagjének tartalmát kérdezi le, és tárolja. 
	 * Egyelemű tagekre vonatkozik.
	 * @param root Element
	 * @param gameElement Element
	 * @param children NodeList
	 * @param elementName String
	 */
	private void getLabel(Element root,Element gameElement,NodeList children,String elementName){
		children = root.getElementsByTagName(elementName);
		gameElement = (Element)children.item(0);
		if(elementName.equals("information")) jgd.setCode(gameElement.getAttribute("code"));
	      else if(elementName.equals("name")) jgd.setName(gameElement.getFirstChild().getNodeValue());
	      else if(elementName.equals("description"))jgd.setDescription(gameElement.getFirstChild().getNodeValue());
	      else if(elementName.equals("date")) jgd.setDate(gameElement.getFirstChild().getNodeValue());
	      else if(elementName.equals("col1")) jgd.setCol1(gameElement.getFirstChild().getNodeValue());
	      else if(elementName.equals("col2")) jgd.setCol2(gameElement.getFirstChild().getNodeValue());
	      else if(elementName.equals("row1")) jgd.setRow1(gameElement.getFirstChild().getNodeValue());
	      else if(elementName.equals("row2")) jgd.setRow2(gameElement.getFirstChild().getNodeValue());
	}
	/**
	 * A kinyert adatokból, létrehozunk egy kiírható formát. Html tálázatban.
	 * @param rowL String[]
	 * @param colL String[]
	 * @param dt Double[]
	 * @param tbWidth int
	 * @return String
	 */
	private String createGameContent(String [] rowL, String[] colL, Double[][] dt,int tbWidth){
		StringBuffer sb = new StringBuffer("<table border=1 width="+tbWidth+"><tr><td align=center>/</td>");
		for(int i=0;i<colL.length;i++){
			sb.append("<td>"+colL[i]+"</td>");
		}
		sb.append("</tr>");
		
		for(int i=0; i<rowL.length;i++){
			sb.append("<tr>");
			sb.append("<td>"+rowL[i]+"</td>");
			for(int j=0;j<colL.length;j++){
				sb.append("<td>"+dt[i][j]+"</td>");
			}
			sb.append("</tr>");
		}
		sb.append("</table>");
		return sb.toString();
	}
	
	
	@Override
	public void playGame() {
		Double[][] data=jgd.getAdata();
		Double a = data[1][1]-data[0][1];
		Double alfa = data[0][0]-data[0][1]-data[1][0]+data[1][1];
		Double lambda=a/alfa;

		data=jgd.getBdata();
		Double b = data[1][1]-data[1][0];
		Double beta = data[0][0]-data[0][1]-data[1][0]+data[1][1];
		Double mu=b/beta;
				
		
		//feltételek
		if(alfa.compareTo(0.0)==0 && a.compareTo(0.0)==0){
			double[][] drawLineA={{0.0,0.0},{0.0,1.0},{1.0,1.0},{1.0,1.0},{1.0,0.0},{1.0,0.0},{0.0,0.0}};
			jk0002.getGr().setDrawLineA(drawLineA);
		}
		if(beta.compareTo(0.0)==0 && b.compareTo(0.0)==0){
			double[][] drawLineB={{0.0,0.0},{0.0,1.0},{1.0,1.0},{1.0,1.0},{1.0,0.0},{1.0,0.0},{0.0,0.0}};
			jk0002.getGr().setDrawLineB(drawLineB);
		}
		if(alfa.compareTo(0.0)==0 && a.compareTo(0.0)>0){
			double[][] drawLineA={{0.0,0.0},{0.0,1.0}};
			jk0002.getGr().setDrawLineA(drawLineA);
		}
		if(beta.compareTo(0.0)==0 && b.compareTo(0.0)>0){
			double[][] drawLineB={{0.0,0.0},{1.0,0.0}};
			jk0002.getGr().setDrawLineB(drawLineB);
		}
		if(alfa.compareTo(0.0)==0 && a.compareTo(0.0)<0){
			double[][] drawLineA={{1.0,0.0},{1.0,1.0}};
			jk0002.getGr().setDrawLineA(drawLineA);
		}
		if(beta.compareTo(0.0)==0 && b.compareTo(0.0)<0){
			double[][] drawLineB={{0.0,1.0},{1.0,1.0}};
			jk0002.getGr().setDrawLineB(drawLineB);
		}
		if(alfa.compareTo(0.0)!=0 && lambda==0){
			double[][] drawLineA={{0.0,0.0},{1.0,0.0},{1.0,0.0},{1.0,1.0}};
			jk0002.getGr().setDrawLineA(drawLineA);	
		}
		if(beta.compareTo(0.0)!=0 && mu==0){
			double[][] drawLineB={{0.0,0.0},{0.0,1.0},{0.0,1.0},{1.0,1.0}};
			jk0002.getGr().setDrawLineB(drawLineB);	
		}
		if(alfa.compareTo(0.0)>0 && lambda>0 && lambda<1){
			double[][] drawLineA={{0.0,0.0},{0.0,lambda},{0.0,lambda},{1.0,lambda},{1.0,lambda},{1.0,1.0}};
			jk0002.getGr().setDrawLineA(drawLineA);
		}
		if(beta.compareTo(0.0)>0 && mu>0 && mu<1){
			double[][] drawLineB={{0.0,0.0},{mu,0.0},{mu,0.0},{mu,1.0},{mu,1.0},{1.0,1.0}};
			jk0002.getGr().setDrawLineB(drawLineB);
		}
		if(alfa.compareTo(0.0)<0 && lambda>0 && lambda<1){
			//System.out.println(a+","+alfa+","+lambda);
			double[][] drawLineA={{1.0,0.0},{1.0,lambda},{1.0,lambda},{0.0,lambda},{0.0,lambda},{0.0,1.0}};
			jk0002.getGr().setDrawLineA(drawLineA);
		}
		if(beta.compareTo(0.0)<0 && mu>0 && mu<1){
			double[][] drawLineB={{1.0,0.0},{mu,0.0},{mu,0.0},{mu,1.0},{mu,1.0},{0.0,1.0}};
			jk0002.getGr().setDrawLineB(drawLineB);
		}
		if(alfa.compareTo(0.0)<0 && lambda<0){
			double[][] drawLineA={{0.0,0.0},{0.0,1.0}};
			jk0002.getGr().setDrawLineA(drawLineA);			
		}
		if(beta.compareTo(0.0)<0 && mu<0){
			double[][] drawLineB={{0.0,0.0},{1.0,0.0}};
			jk0002.getGr().setDrawLineB(drawLineB);			
		}
		if(alfa.compareTo(0.0)>0 && lambda<0){
			double[][] drawLineA={{1.0,0.0},{1.0,1.0}};
			jk0002.getGr().setDrawLineA(drawLineA);			
		}
		if(beta.compareTo(0.0)>0 && mu<0){
			double[][] drawLineB={{0.0,1.0},{1.0,1.0}};
			jk0002.getGr().setDrawLineB(drawLineB);			
		}
		
		if(alfa.compareTo(0.0)<0 && lambda==0){
			double[][] drawLineA={{0.0,1.0},{0.0,0.0},{0.0,0.0},{1.0,0.0}};
			jk0002.getGr().setDrawLineA(drawLineA);			
		}
		if(beta.compareTo(0.0)<0 && mu==0){
			double[][] drawLineB={{0.0,1.0},{0.0,0.0},{0.0,0.0},{1.0,0.0}};
			jk0002.getGr().setDrawLineB(drawLineB);			
		}
		if(alfa.compareTo(0.0)>0 && lambda==1){
			double[][] drawLineA={{0.0,0.0},{0.0,1.0},{0.0,1.0},{1.0,1.0}};
			jk0002.getGr().setDrawLineA(drawLineA);			
		}
		if(beta.compareTo(0.0)>0 && mu==1){
			double[][] drawLineB={{0.0,0.0},{1.0,0.0},{1.0,0.0},{1.0,1.0}};
			jk0002.getGr().setDrawLineB(drawLineB);			
		}
		if(alfa.compareTo(0.0)<0 && lambda==1){
			double[][] drawLineA={{0.0,1.0},{1.0,1.0},{1.0,1.0},{1.0,0.0}};
			jk0002.getGr().setDrawLineA(drawLineA);			
		}
		if(beta.compareTo(0.0)<0 && mu==1){
			double[][] drawLineB={{1.0,0.0},{1.0,1.0},{1.0,1.0},{0.0,1.0}};
			jk0002.getGr().setDrawLineB(drawLineB);			
		}
		if(alfa.compareTo(0.0)>0 && lambda>1){
			double[][] drawLineA={{0.0,0.0},{0.0,1.0}};
			jk0002.getGr().setDrawLineA(drawLineA);			
		}
		if(beta.compareTo(0.0)>0 && mu>1){
			double[][] drawLineB={{0.0,0.0},{1.0,0.0}};
			jk0002.getGr().setDrawLineB(drawLineB);			
		}
		if(alfa.compareTo(0.0)<0 && lambda>1){
			double[][] drawLineA={{1.0,0.0},{1.0,1.0}};
			jk0002.getGr().setDrawLineA(drawLineA);			
		}
		if(beta.compareTo(0.0)<0 && mu>1){
			double[][] drawLineB={{0.0,1.0},{1.0,1.0}};
			jk0002.getGr().setDrawLineB(drawLineB);			
		}
		
		
		
		//egyensúlypontok
		int k=-1;
		double[][] drawLineA=jk0002.getGr().getDrawLineA();
		double[][] drawLineB=jk0002.getGr().getDrawLineB();
		double[][] equilibria=new double[4][2];
		
		for(int i=0;i<drawLineA.length;i++){
			for(int j=0;j<drawLineB.length;j++){
				if(drawLineA[i][0]==drawLineB[j][0] && drawLineA[i][1]==drawLineB[j][1]){
					boolean isA=false;
					for(int l=0;l<=k;l++){
						if(equilibria[l][0]==drawLineA[i][0] && equilibria[l][1]==drawLineA[i][1]){
							isA=true;
							break;
						}
					}
					if(!isA){
						k++;
						equilibria[k][0]=drawLineA[i][0];
						equilibria[k][1]=drawLineA[i][1];
					}
				}
			}
		}
		
		if(lambda>0 && lambda<1 && mu>=0 && mu<=1){
			k++;
			equilibria[k][0]=mu;
			equilibria[k][1]=lambda;
		}else if(lambda>=0 && lambda<=1 && mu>0 && mu<1){
			k++;
			equilibria[k][0]=mu;
			equilibria[k][1]=lambda;
		}
		String points="{";
		for(int i=0;i<=k;i++){
			points+="{"+equilibria[i][0]+","+equilibria[i][1]+"}";
		}
		points+="}";
		jgd.setEquilibriaLength(k);
		jgd.setEquilibriaString(points);
		jk0002.getGr().setEquilibria(equilibria);
		jk0002.getGr().setEquilibriaLength(k);
		
		//String[] rws={jgd.getRow1(),jgd.getRow2()};
		//String[] cls={jgd.getCol1(),jgd.getCol2()};
		//jk0002.getGameResults().setText("<html>"+createGameContent(rws, cls, jgd.getAdata(), 200)+"<br>"+createGameContent(rws, cls, jgd.getBdata(), 200)+"Egyensúlypont: "+points+"</html>");
		jk0002.getGameResults().setText("<html><p>Egyensúlypont: "+points+
				"<br>a: "+a +
				"<br>Alfa: "+alfa +
				"<br>Lambda: "+lambda +
				"<hr>"+
				"b: "+b +
				"<br>Béta: "+beta +
				"<br>Mu: "+mu +
				"</p></html>");
		jk0002.getGr().repaint();
		jgd.setToExcel(true);
	}
	public Jatek0002GameData getJgd() {
		return jgd;
	}
	public Jatek0002Panel getJk0002() {
		return jk0002;
	}

	
	
}
