package com.rjconsultores.ventaboletos.vo.layout;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang.StringUtils;

import com.rjconsultores.ventaboletos.entidad.DetDiagramaAutobus;

public class DiagramaPoltronas implements Comparable<DiagramaPoltronas> {
	
	private static Integer TOTAL_FILAS = 12;
	private static Integer TOTAL_COLUNAS = 21;

	private Integer fila;

	private List<Coluna> colunas;

	public DiagramaPoltronas() {
		super();
	}
	
	public DiagramaPoltronas(Integer fila) {
		this();
		this.fila = fila;
	}

	public DiagramaPoltronas(Short fila) {
		this();
		this.fila = fila.intValue();
	}

	public class Coluna implements Comparable<Coluna> {

		private Integer coluna;
		
		private DiagramaPoltronas fila;

		private List<Poltrona> poltronas;

		public Coluna() {
			super();
		}
		
		public Coluna(Integer coluna, DiagramaPoltronas fila) {
			this();
			this.fila = fila;
			this.coluna = coluna;
		}

		public Coluna(Short coluna, DiagramaPoltronas fila) {
			this();
			this.fila = fila;
			this.coluna = coluna.intValue();
		}

		public Integer getColuna() {
			return coluna;
		}

		public void setColuna(Integer coluna) {
			this.coluna = coluna;
		}

		@Override
		public int compareTo(Coluna o) {
			return this.getColuna().compareTo(o.getColuna());
		}

		public List<Poltrona> getPoltronas() {
			return poltronas;
		}

		public DiagramaPoltronas getFila() {
			return fila;
		}

		public void setFila(DiagramaPoltronas fila) {
			this.fila = fila;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + ((coluna == null) ? 0 : coluna.hashCode());
			result = prime * result + ((fila == null) ? 0 : fila.hashCode());
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			Coluna other = (Coluna) obj;
			if (coluna == null) {
				if (other.coluna != null)
					return false;
			} else if (!coluna.equals(other.coluna))
				return false;
			if (fila == null) {
				if (other.fila != null)
					return false;
			} else if (!fila.equals(other.fila))
				return false;
			return true;
		}
		
		public void adicionarPoltrona(String asiento, Boolean vendible) {
			Poltrona poltrona = new Poltrona(getFila(), this, asiento, vendible);
			if(poltronas == null) {
				poltronas = new ArrayList<DiagramaPoltronas.Poltrona>();
				poltronas.add(poltrona);
			} else {
				int index = poltronas.indexOf(poltrona);
				if(index > -1) {
					poltronas.set(index, poltrona);
				} else {
					poltronas.add(poltrona);
				}
			}
		}

	}

	public class Poltrona {
		
	    private static final String CLASS_GREEN = "myGreen";
	    private static final String CLASS_GREY = "myGrey";
	    private static final String CLASS_WHITE = "myWhite";

		private DiagramaPoltronas fila;
		private Coluna coluna;
		private String asiento;
		
		private String sClass;
		private Boolean vendible;
		
		public Poltrona(DiagramaPoltronas fila, Coluna coluna, String asiento, Boolean vendible) {
			this.fila = fila;
			this.coluna = coluna;
			this.asiento = asiento;
			this.vendible = vendible;
			sClass = CLASS_GREY;
			if(StringUtils.isBlank(asiento)) {
				sClass = CLASS_WHITE;
			} else if(vendible != null && vendible) {
				sClass = CLASS_GREEN;
			}
		}

		public DiagramaPoltronas getFila() {
			return fila;
		}

		public void setFila(DiagramaPoltronas fila) {
			this.fila = fila;
		}

		public Coluna getColuna() {
			return coluna;
		}

		public void setColuna(Coluna coluna) {
			this.coluna = coluna;
		}

		public String getAsiento() {
			return asiento;
		}

		public void setAsiento(String asiento) {
			this.asiento = asiento;
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + getOuterType().hashCode();
			result = prime * result + ((asiento == null) ? 0 : asiento.hashCode());
			result = prime * result + ((coluna == null) ? 0 : coluna.hashCode());
			result = prime * result + ((fila == null) ? 0 : fila.hashCode());
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			Poltrona other = (Poltrona) obj;
			if (!getOuterType().equals(other.getOuterType()))
				return false;
			if (asiento == null) {
				if (other.asiento != null)
					return false;
			} else if (!asiento.equals(other.asiento))
				return false;
			if (coluna == null) {
				if (other.coluna != null)
					return false;
			} else if (!coluna.equals(other.coluna))
				return false;
			if (fila == null) {
				if (other.fila != null)
					return false;
			} else if (!fila.equals(other.fila))
				return false;
			return true;
		}

		private DiagramaPoltronas getOuterType() {
			return DiagramaPoltronas.this;
		}

		@Override
		public String toString() {
			return "bbtn_" + fila.getFila() + "_" + coluna.getColuna();
		}

		public String getsClass() {
			return sClass;
		}

		public void setsClass(String sClass) {
			this.sClass = sClass;
		}
		
		public Boolean getNotVendible() {
			return !getVendible();
		}

		public Boolean getVendible() {
			return vendible;
		}

		public void setVendible(Boolean vendible) {
			this.vendible = vendible;
		}

	}

	public Integer getFila() {
		return fila;
	}

	public void setFila(Integer fila) {
		this.fila = fila;
	}

	public List<Coluna> getColunas() {
		return colunas;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + fila;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		DiagramaPoltronas other = (DiagramaPoltronas) obj;
		if (fila != other.fila)
			return false;
		return true;
	}

	@Override
	public int compareTo(DiagramaPoltronas o) {
		return this.getFila().compareTo(o.getFila());
	}
	
	public static List<DiagramaPoltronas> getLayoutVazio() {
		List<DiagramaPoltronas> layout = new ArrayList<DiagramaPoltronas>();
		for (int i = 1; i <= TOTAL_FILAS; i++) {
			DiagramaPoltronas fila = new DiagramaPoltronas(i);
			for (int j = 1; j <= TOTAL_COLUNAS; j++) {
				Coluna coluna = fila.new Coluna(j, fila);
				coluna.adicionarPoltrona("",false);
				fila.adicionarColuna(coluna);
			}
			layout.add(fila);
		}
		Collections.sort(layout);
		for (DiagramaPoltronas fila : layout) {
			Collections.sort(fila.getColunas());
		}
		return layout;
	}
	
	private void adicionarColuna(Coluna coluna) {
		if(colunas == null) {
			colunas = new ArrayList<DiagramaPoltronas.Coluna>();
			colunas.add(coluna);
		} else {
			int index = colunas.indexOf(coluna);
			if(index > -1) {
				colunas.set(index, coluna);
			} else {
				colunas.add(coluna);
			}
		}
	}

	public static List<DiagramaPoltronas> carregarLayoutExistente(List<DetDiagramaAutobus> detDiagramaAutobus) {
		List<DiagramaPoltronas> layout = getLayoutVazio();
		for (DetDiagramaAutobus diagramaAutobus : detDiagramaAutobus) {
			DiagramaPoltronas fila = new DiagramaPoltronas(diagramaAutobus.getNumefila());
			int index = layout.indexOf(fila);
			if(index > -1) {
				fila = layout.get(index);
			}

			Coluna coluna = fila.new Coluna(diagramaAutobus.getNumecolumna(), fila);
			fila.adicionarColuna(coluna);
			
			coluna.adicionarPoltrona(diagramaAutobus.getAsiento(), diagramaAutobus.getVendible());
			
			if(index == -1) {
				layout.add(fila);
			}
			
		}
		return layout;
	}

}