package wto.prito.inf66268.util;

import java.util.*;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.NumberFormat.*;

import wto.prito.inf66268.exceptions.NotANumberException;
import wto.prito.inf66268.exceptions.UncorrectOperationException;

public class Sheet{	
	
	/**
	 * Map contain all cells in the sheet
	 */
	private Map<String, Cell> sheetMap = new HashMap<String, Cell>();	
	private Map<String, Cell> sheetMapOut = new HashMap<String, Cell>();
			
	private char maxColl;
	private int maxRow;
	
	public void addCell(int row, char coll, String value){
		sheetMap.put(""+coll+row, new Cell(value));		
	}	
	
	public void setMaxCollAndRow(char maxColl, int maxRow){
		this.maxColl = maxColl;
		this.maxRow = maxRow;
	}
	
	public String getStringMap(){
		String resultString = "";
				
		for(int i = 1;i <= maxRow;i++){
			for(char j = 'A';j <= maxColl;j++){
				if (sheetMap.get(""+j+i) != null){
					resultString += sheetMap.get(""+j+i).getCellValue();
					resultString += "|";
				}
			}
			resultString += "\n";
		}
		
		return resultString;
	}
	
	public String getStringMapOut(){
		String resultString = "";
				
		for(int i = 1;i <= maxRow;i++){
			for(char j = 'A';j <= maxColl;j++){
				if (sheetMap.get(""+j+i) != null){
					resultString += sheetMapOut.get(""+j+i).getCellValue();
					resultString += "|";
				}
			}
			resultString += "\n";
		}
		
		return resultString;
	}
	
	private Cell getCell(String adres){
		return sheetMap.get(adres);
	}
	
	private Cell getCell(char coll, int row){
		return sheetMap.get("" + coll + row);
	}
	
	public void countSheet(){		
		for(int i = 1;i <= maxRow;i++){
			for(char j = 'A';j <= maxColl;j++){
				if (sheetMap.get(""+j+i) != null){
					if(sheetMap.get(""+j+i).isOperation()){
						sheetMapOut.put("" + j + i, new Cell(""));
						countCell(sheetMap.get(""+j+i), sheetMapOut.get(""+j+i));
					}
					else
						sheetMapOut.put("" + j + i, new Cell(sheetMap.get("" + j + i).getCellValue()));
				}				
			}		
		}
	}
	
	private void countCell(Cell cellIn, Cell cellOut){
		String regX = "[*=+/-]";		
		
		if(cellIn.getCellValue().split(regX).length == 2)
			cellOut.setCellValue(operateOne(cellIn.getCellValue().split(regX)[1]));
		else if(cellIn.getCellValue().split(regX).length == 3)
			cellOut.setCellValue(operateTwo(cellIn.getCellValue().split("=")[1]));		
	}
	
	private String operateOne(String value){
		if(value.charAt(0) >= 'A' && value.charAt(0) <= 'Z'){
			if(this.getCell(value) != null && this.getCell(value).getCellValue().charAt(0) != '=')
				return this.getCell(value).getCellValue();
			else
				return "=" + value;
		}	
		return value;
		
	}
	
	private String operateOneGetNumber(String value) throws NotANumberException{
		try{
		if(value.charAt(0) >= 'A' && value.charAt(0) <= 'Z'){
			if(this.getCell(value) != null){
				System.out.println(this.getCell(value).getCellValue());
				return String.valueOf(NumberFormat.getInstance().parse(this.getCell(value).getCellValue()).floatValue());//Float.parseFloat(this.getCell(value).getCellValue());
			}
			return String.valueOf(NumberFormat.getInstance().parse(value).floatValue());//Float.parseFloat(value);
		}	
		return String.valueOf(NumberFormat.getInstance().parse(value).floatValue());//Float.parseFloat(value);
		}
		catch(ParseException e){
			return value;
		}
		
	}
	
	private String operateTwo(String value){
		float retValue = 0;
		try{
			if(value.split("[+]").length == 2){				
				retValue = Float.parseFloat(operateOneGetNumber(value.split("[+]")[0])) + Float.parseFloat(operateOneGetNumber(value.split("[+]")[1]));
				System.out.println("TO " + NumberFormat.getInstance().format((retValue)));
				return floatToInt(String.valueOf(NumberFormat.getInstance().format((retValue))));				
			}
			else if(value.split("[-]").length == 2){
				retValue = Float.parseFloat(operateOneGetNumber(value.split("[-]")[0])) - Float.parseFloat(operateOneGetNumber(value.split("[-]")[1]));
				return floatToInt(String.valueOf(NumberFormat.getInstance().format((retValue))));
			}						
			return value;
		}
		catch(NotANumberException e){
			return "=" + value;
		}
		catch(NumberFormatException e){
			return "=" + value;
		}
		
	}
	
	private String floatToInt(String value){
		if(value.charAt(value.length() - 1) == '0' && value.charAt(value.length() - 2) == '.')
			return value.substring(0, value.length() - 2);
		return value;
	}
	
	public boolean isNull(){
		if(sheetMap == null)
			return true;
		return false;
	}
}

