/*******************************************************************************
 * This file is part of GECAMed.
 * 
 * GECAMed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (L-GPL) as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GECAMed is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License (L-GPL)
 * along with GECAMed.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * GECAMed is Copyrighted by the Centre de Recherche Public Henri Tudor (http://www.tudor.lu)
 * (c) CRP Henri Tudor, Luxembourg, 2008
 *******************************************************************************/
package lu.tudor.santec.gecamed.patient.gui.hospitalisation.editor;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.swing.table.AbstractTableModel;

import lu.tudor.santec.gecamed.patient.ejb.entity.beans.HospitalDepartment;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.HospitalisationClass;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.HospitalisationPeriod;
import lu.tudor.santec.gecamed.patient.ejb.entity.beans.HospitalisationStatus;
import lu.tudor.santec.i18n.Translatrix;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

public class HospitalisationPeriodTableModel extends AbstractTableModel {

	/**
	 * static logger for this class
	 */
	private static Logger logger = Logger
			.getLogger(HospitalisationPeriodTableModel.class.getName());
	
	private boolean editable = true;
	private static final long serialVersionUID = 1L;
	private ArrayList<HospitalisationPeriod> data;
	private String[] columns = {
			Translatrix.getTranslationString("hosp.description"),
			Translatrix.getTranslationString("hosp.class"),
			Translatrix.getTranslationString("hosp.department"), 
			Translatrix.getTranslationString("hosp.bed"), 
			Translatrix.getTranslationString("hosp.start"), 
			Translatrix.getTranslationString("hosp.end"), 
			Translatrix.getTranslationString("hosp.status")
	};
	private Class[] columnsClasses = {String.class, String.class, String.class, String.class, Date.class
			, Date.class, HospitalisationStatus.class};
	
	
	
	/**
	 * @param data
	 */
	public void setData(Collection<HospitalisationPeriod> data) {
		if (data != null) {
			this.data = new ArrayList<HospitalisationPeriod>(data);
		} else {
			this.data = null;
		}
		this.fireTableDataChanged();
	}
	
	/* (non-Javadoc)
	 * @see javax.swing.table.TableModel#getRowCount()
	 */
	public int getRowCount() {
		try {
			return data.size();
		} catch (Exception e) {
			return 0;
		}
	}

	public int getColumnCount() {
		return columns.length;
	}
	
	public String getColumnName(int column) {
		return columns[column];
	}
	
	public Class<?> getColumnClass(int column) {
		return columnsClasses[column];
	}

	public Object getValueAt(int rowIndex, int columnIndex) {
		HospitalisationPeriod hp = data.get(rowIndex);
		try {
			switch (columnIndex) {
			case 0:
				return hp.getDescription();
			case 1:
				return hp.getHospitalisationClass();
			case 2:
				return hp.getHospitalDepartment();
			case 3:
				return hp.getHospitalBed();
			case 4:
				return hp.getStartDate();
			case 5:
				return hp.getEndDate();
			case 6:
				return hp.getHospitalisationStatus();
			default:
				return "";
			}
		} catch (Exception e) {
			return "";
		}
	}

	public boolean isCellEditable(int rowIndex, int columnIndex) {
		return editable;
	}

	/* (non-Javadoc)
	 * @see javax.swing.table.AbstractTableModel#setValueAt(java.lang.Object, int, int)
	 */
	@Override
	public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
		HospitalisationPeriod hp = data.get(rowIndex);
		try {
			switch (columnIndex) {
			case 0:
				hp.setDescription((String) aValue);
				break;
			case 1:
				hp.setHospitalisationClass((HospitalisationClass) aValue);
				break;
			case 2:
				hp.setHospitalDepartment((HospitalDepartment) aValue);
				break;
			case 3:
				hp.setHospitalBed((String) aValue);
				break;
			case 4:
				hp.setStartDate((Date) aValue);
				break;
			case 5:
				hp.setEndDate((Date) aValue);
				break;
			case 6:
				hp.setHospitalisationStatus((HospitalisationStatus) aValue);
				break;
				
			}
		} catch (Exception e) {
			logger.log(Level.WARN, "showing HospitalisationPeriod failed", e);
		}
	}
	
	public HospitalisationPeriod getHospitalisationPeriod(int row) {
		return data.get(row);
	}
	
	public HospitalisationPeriod createNextHospitalisationPeriod() {
		HospitalisationPeriod hp = new HospitalisationPeriod();
		try {
			hp.setStartDate(data.get(data.size()-1).getEndDate());
		} catch (Exception e) {
			hp.setStartDate(new Date());
		}
		try {
			hp.setHospitalBed(data.get(data.size()-1).getHospitalBed());
		} catch (Exception e) {
		}
		try {
			hp.setHospitalisationClass(data.get(data.size()-1).getHospitalisationClass());
		} catch (Exception e) {
		}
		try {
			hp.setHospitalDepartment(data.get(data.size()-1).getHospitalDepartment());
		} catch (Exception e) {
		}
		return hp;
	}
	
	
	/**
	 * Adds a new HopsitalisationPeriod to the data set.
	 * If data equals null, it will be initialized
	 * 
	 * @param hPeriod
	 */
	public void addHospitalisationPeriod(HospitalisationPeriod hPeriod) {
		/* =================================================== */
		// first check if data equals null
		if (this.data == null) {
			// init data
			this.data = new ArrayList<HospitalisationPeriod>();
		}
		// add the period
		if (hPeriod != null) {
			this.data.add(hPeriod);
			// update
			fireTableDataChanged();
		}
		else
			throw new NullPointerException("Given HospitalisationPeriod is null");
			
		
		/* =================================================== */
	}
	
	
	/**
	 * Removes a periode at the given row
	 * 
	 * @param row
	 */
	public void removeHospitalisationPeriod(int row) {
		/* =================================================== */
		// if there is something selected
		if (row > -1) {
			/* ----------------------------------------------- */
				this.data.remove(row);
				fireTableDataChanged();
			/* ----------------------------------------------- */
		}
		/* =================================================== */
	}
	
	
	/**
	 * returns the current data set of the model
	 * 
	 * @return
	 */
	public List<HospitalisationPeriod> getData() {
		/* =================================================== */
		return this.data;
		/* =================================================== */
	}

	/**
	 * @return Returns the editable.
	 */
	public boolean isEditable() {
		return editable;
	}

	/**
	 * @param editable The editable to set.
	 */
	public void setEditable(boolean editable) {
		this.editable = editable;
	}
	
}
