/*******************************************************************************
 * 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.prescription.gui.drug.lists.cefip;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import lu.tudor.santec.gecamed.core.gui.utils.IChangeListener;
import lu.tudor.santec.gecamed.prescription.gui.drug.lists.cefip.importer.CefipImportWorker;

/**
 * Model to controll the cefip files.
 * Holds the filenames to the DFB files for ATCClasses, Manufacturer and drug list. It tests if the files 
 * are ready to use.
 * 
 * @author martin.heinemann@tudor.lu
 *
 *
 * @version
 * <br>$Log: DrugFileModel.java,v $
 * <br>Revision 1.6  2009-05-07 15:56:26  heinemann
 * <br>import of new cefip file format in ms access.
 * <br>using lib jackccess
 * <br>
 * <br>Revision 1.5  2008-09-25 09:43:10  heinemann
 * <br>fixed copyrights
 * <br>
 * <br>Revision 1.4  2008-02-11 16:51:50  heinemann
 * <br>moved IChangeListener to core
 * <br>
 * <br>Revision 1.3  2008-01-15 09:58:55  heinemann
 * <br>better documentation
 * <br>
 * <br>Revision 1.2  2007/03/02 08:28:44  hermen
 * <br>initial checkin after the merge of PatientModuleRebuild with the main HEAD
 * <br>
 * <br>Revision 1.1.2.1  2006/12/20 13:47:04  heinemann
 * <br>*** empty log message ***
 * <br>
 */
public class DrugFileModel {
	
	/* *******************************************************
	 *  Constants for the files
	 */
	
	private final String CEFIP_FILE = "CEFIP2.DBF";
	private final String ATC_FILE = "ATC.DBF";
	private final String MANUFACTURER_FILE = "Four.dbf";
	
	/* ------------------------------------------------------ */
	// Constants for the return state of a test method
	public static final Integer FILE_NO_STATE = -1;
	public static final Integer FILE_OK = 0;
	public static final Integer FILE_IS_DIRECTORY = 1;
	public static final Integer FILE_NOT_READABLE = 2;
	
	/* ------------------------------------------------------ */
	public static final Integer ATC          = 1;
	public static final Integer DRUG         = 2;
	public static final Integer MANUFACTURER = 3;
	public static final Integer CEFIP_MDB 	 = 4;
	/* ------------------------------------------------------- */
	public static final Integer CEFIP_VERSION_OLD  = 1;
	public static final Integer CEFIP_VERSION_2008 = 2;
	
	
	/* ****************************************************** */
	
	
	
	
	private HashMap<Integer, Integer> stateHash = new HashMap<Integer, Integer>();
	
	private Integer cefipVersion = CEFIP_VERSION_OLD;
	
	private String cefipDir;
	private String atcFile;
	private String manufacturerFile;
	private String drugFile;
	
	private CefipImportWorker worker;
	
	private List<IChangeListener> changeListener = new ArrayList<IChangeListener>();
	/**
	 * The Access file of the new cefip list
	 */
	private File mdbFile;

	/* **********************************************************
	 * Body
	 */
	
	public DrugFileModel() {
		/* ====================================================== */
		this.worker = new CefipImportWorker();
		// init 
		reset();
		/* ====================================================== */
	}
	
	
	/**
	 * Sets the cefip dir
	 * 
	 * @param cefipDir
	 */
	public void setCefipDir(File cefipDir) {
		/* ====================================================== */
		this.cefipDir = cefipDir.getAbsolutePath();
		File cefipF = cefipDir;
		/* ------------------------------------------------------ */
		// check if this not a directory
		if (!cefipF.isDirectory()) {
			/* ------------------------------------------------------ */
			// reset the fields
			reset();
			fireModelChanged();
			/* ------------------------------------------------------- */
			// check for Access database file
			/* ------------------------------------------------------- */
			setMdbFile(cefipF);
			/* ------------------------------------------------------ */
		} else {
			/* ------------------------------------------------------ */
			// set each file for old cefip list
			/* ------------------------------------------------------- */
			this.setAtcFile(cefipDir+"/"+ATC_FILE);
			this.setManufacturerFile(cefipDir+"/"+MANUFACTURER_FILE);
			this.setDrugFile(cefipDir+"/"+CEFIP_FILE);
			/* ------------------------------------------------------ */
		}
		fireModelChanged();
		/* ====================================================== */
	}


	/**
	 * Resets the pathes for the files
	 */
	private void reset() {
		/* ====================================================== */
		// atc
		atcFile = "";
		stateHash.put(ATC, FILE_NO_STATE);
		// drug
		drugFile = "";
		stateHash.put(DRUG, FILE_NO_STATE);
		// manufacuter
		manufacturerFile = "";
		stateHash.put(MANUFACTURER, FILE_NO_STATE);
		/* ====================================================== */
	}
	
	
	/**
	 * @param accessFile
	 */
	public void setMdbFile(File accessFile) {
		/* ================================================== */
		this.mdbFile = accessFile;
		/* ------------------------------------------------------- */
		Integer state = worker.testMdbFile(this.mdbFile);
		stateHash.put(CEFIP_MDB, state);
		this.cefipVersion = CEFIP_VERSION_2008;
		/* ================================================== */
	}
	
	
	/**
	 * Sets and checks the atc dbf file
	 * 
	 * @param atcFile
	 * 
	 */
	public void setAtcFile(String atcFile) {
		/* ====================================================== */
		this.atcFile = atcFile;
		File atcF = new File(this.atcFile);
		/* ------------------------------------------------------ */
		Integer state = worker.testAtcFile(atcF);
		/* ------------------------------------------------------ */
		// check the file
		stateHash.put(ATC, state);
		/* ------------------------------------------------------ */
		/* ====================================================== */
	}
	
	/**
	 * Sets the manufacture file and test the integrity
	 * 
	 * @param manuFile
	 */
	public void setManufacturerFile(String manuFile) {
		/* ====================================================== */
		this.manufacturerFile = manuFile;
		File manuF = new File(this.manufacturerFile);
		/* ------------------------------------------------------ */
		// check the file
		Integer state = worker.testManufacturer(manuF);
		/* ------------------------------------------------------ */
		stateHash.put(MANUFACTURER, state);
		/* ====================================================== */
	}
	
	/**
	 * Sets the drug file and test the integrity
	 * 
	 * @param manuFile
	 */
	public void setDrugFile(String drugFile) {
		/* ====================================================== */
		this.drugFile = drugFile;
		File drugF = new File(this.drugFile);
		/* ------------------------------------------------------ */
		// check the file
		Integer state = worker.testCefipList(drugF);
		/* ------------------------------------------------------ */
		stateHash.put(DRUG, state);
		/* ====================================================== */
	}
	
	/**
	 * Notify all listeners
	 */
	public void fireModelChanged() {
		/* ====================================================== */
		if (changeListener != null)
			for(IChangeListener l : changeListener)
				l.fireEvent();
		/* ====================================================== */
	}
	
	/* *************************************************************
	 * Getter/Setter
	 */
	
	/**
	 * @return the allOk
	 */
	public boolean isAllOk() {
		/* ====================================================== */
		if (this.cefipVersion.equals(CEFIP_VERSION_OLD)) {
			if (stateHash.get(ATC) == FILE_OK
					&& stateHash.get(MANUFACTURER) == FILE_OK
					&& stateHash.get(DRUG) == FILE_OK)
				return true;
			else
				return false;
		} else {
			if (stateHash.get(CEFIP_MDB) == FILE_OK)
				return true;
			else
				return false;
		}
		/* ====================================================== */
	}
	
	/**
	 * returns the state of a file
	 * 
	 * @param type
	 * @return
	 */
	public Integer getState(Integer type) {
		/* ====================================================== */
		return stateHash.get(type);
		/* ====================================================== */
	}
	
	/**
	 * @return the atcFile
	 */
	public String getAtcFile() {
		return atcFile;
	}
	/**
	 * @return the cefipDir
	 */
	public String getCefipDir() {
		return cefipDir;
	}
	/**
	 * @return the drugFile
	 */
	public String getDrugFile() {
		return drugFile;
	}
	/**
	 * @return the manufacturerFile
	 */
	public String getManufacturerFile() {
		return manufacturerFile;
	}
	
	
	/**
	 * Add a changelistener.
	 * Will be notified, when something changed in the model
	 * 
	 * @param l
	 */
	public void addChangeListener(IChangeListener l) {
		/* ====================================================== */
		this.changeListener.add(l);
		/* ====================================================== */
	}
	
	
	/**
	 * Return the CefipImprotWorker
	 * @return
	 */
	public CefipImportWorker getWorker() {
		/* ====================================================== */
		return this.worker;
		/* ====================================================== */
	}


	/**
	 * @return the cefipVersion
	 */
	public Integer getCefipVersion() {
		/* ====================================================== */
		return cefipVersion;
		/* ====================================================== */
	}
	
	
	
	/* ----------------------------------------------------------- 
	 * End of Getter/Setter
	 * *********************************************************** */
	
	
	
}
