/*******************************************************************************
 * 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.address.gui.addressmanagement;

import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

import lu.tudor.santec.gecamed.address.ejb.entity.beans.Locality;
import lu.tudor.santec.gecamed.address.ejb.entity.beans.Zip;
import lu.tudor.santec.gecamed.address.ejb.session.beans.AddressImportBean;
import lu.tudor.santec.gecamed.address.ejb.session.beans.AddressManagerBean;
import lu.tudor.santec.gecamed.address.ejb.session.interfaces.AddressImportInterface;
import lu.tudor.santec.gecamed.address.ejb.session.interfaces.AddressManagerInterface;
import lu.tudor.santec.gecamed.address.gui.AddressModuleLoader;
import lu.tudor.santec.gecamed.core.ejb.session.beans.ListManagerBean;
import lu.tudor.santec.gecamed.core.ejb.session.interfaces.ListManagerInterface;
import lu.tudor.santec.gecamed.core.gui.GECAMedColors;
import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedLists;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.GECAMedTab;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.widgets.FileSelectorPanel;
import lu.tudor.santec.gecamed.core.gui.widgets.progress.ProgressDialog;
import lu.tudor.santec.gecamed.core.gui.widgets.progress.ProgressEvent;
import lu.tudor.santec.gecamed.core.gui.widgets.progress.ProgressListener;
import lu.tudor.santec.gecamed.core.utils.GECAMedUtils;
import lu.tudor.santec.gecamed.core.utils.ManagerFactory;
import lu.tudor.santec.i18n.Relocalizable;
import lu.tudor.santec.i18n.Translatrix;

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

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

public class AddressImportPanel extends GECAMedTab implements PropertyChangeListener,
															  ActionListener,
															  ProgressListener,
															  Relocalizable
	{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	/**
	 * static logger for this class
	 */
	private static Logger logger = Logger.getLogger(AddressImportPanel.class.getName());
	
	private AddressImportInterface		m_AddressImportInterface;
	private AddressManagerInterface 	m_AddressManagerInterface;
	
	private JPanel						m_FilePanel;
	private JPanel						m_LocalityPanel;
	private JPanel						m_ZIPPanel;
	
	private TitledBorder				m_FileBorder;
	private TitledBorder				m_LocalityBorder;
	private TitledBorder				m_ZIPBorder;
	
	private JLabel						m_UpdateFileCaption;
	private FileSelectorPanel			m_AddressUpdateFile;
	
	private JLabel						m_LocalitiesCaption;
	private LocalityListBox				m_Localities;
	private JButton						m_AddLocalities;
	private JButton						m_EditLocalities;
	
	private JLabel						m_ZIPsCaption;
	private ZIPListBox					m_ZIPs;
	private JButton						m_AddZIPs;
	private JButton						m_EditZIPs;
	
	private AddressUpdater				m_Updater;
	private ProgressDialog				m_ProgressDialog;
	private int							m_Operation;
	private Long						m_NumberOfLines;

	private JButton m_Import;

	private LocalityEditDialog localityEditDialog;

	private ZipEditDialog zipEditDialog;

	
	private static Logger m_Logger = Logger.getLogger (AddressImportPanel.class.getName());

//---------------------------------------------------------------------------
//***************************************************************************
//* Constants	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

	public static final int	c_ProcessLocalities	= 1;
	public static final int	c_ProcessZIPs		= 2;
	public static final int	c_ImportZIPs		= 3;

	private static final String	c_AddressUpdateFile = "AddressImportPanel.AddressUpdateFileLabel";
	
	//=======================================================================
	//= Layout Strings
	//=======================================================================

	private final static String c_Columns				= "3dlu,fill:400dlu:grow,3dlu";

	private final static String c_Rows					= "3dlu,fill:pref," +
	  													  "3dlu,fill:100dlu:grow," +
	  													  "3dlu,fill:100dlu:grow,3dlu";

	private final static String c_FileColumns 			= "3dlu,fill:max(15dlu;pref)," +
														  "10dlu,fill:max(50dlu;pref)," +
														  "10dlu, fill:pref:grow,3dlu";

	private final static String c_FileRows 				= "3dlu,top:pref,3dlu, top:pref,3dlu";
	
	
	private final static String c_LocalityColumns 		= "3dlu, fill:max(15dlu;pref)," +
	  													  "10dlu,fill:max(50dlu;pref)," +
	  													  "10dlu,fill:pref:grow," +
	  													  "3dlu, fill:max(20dlu;pref)," +
	  													  "3dlu, fill:max(20dlu;pref),3dlu";

	private final static String c_LocalityRows 			= "3dlu,top:100dlu:grow," +
														  "3dlu,top:pref,3dlu";

	private final static String c_ZIPColumns 			= "3dlu, fill:max(15dlu;pref)," +
	  													  "10dlu,fill:max(50dlu;pref)," +
	  													  "10dlu,fill:pref:grow," +
	  													  "3dlu, fill:max(20dlu;pref)," +
	  													  "3dlu, fill:max(20dlu;pref),3dlu";

	private final static String c_ZIPRows 				= "3dlu,top:100dlu:grow," +
	  													  "3dlu,top:pref,3dlu";
	
//---------------------------------------------------------------------------
//***************************************************************************
//* Constructor(s)                                                          *
//***************************************************************************
//---------------------------------------------------------------------------

public AddressImportPanel ()
	{
	CellConstraints	l_Constraints;
	FormLayout		l_Layout;	
	Font			l_CaptionFont;
	
	this.setOpaque(false);

	AddressModuleLoader.InitAddressModule();
	
	l_Constraints  = new CellConstraints();

	this.setTitle(Translatrix.getTranslationString("AddressImportPanel.Title"));
	this.setIcon(AddressModuleLoader.getIconResource("update_addresses.png"));
	
	m_ZIPBorder 	 = new TitledBorder (Translatrix.getTranslationString("AddressImportPanel.ZIPBorderTitle"));
	
	//=======================================================================
	//= Assemble Statement Panel
	//=======================================================================
	
	l_Layout = new FormLayout(c_FileColumns, c_FileRows);

	m_FileBorder 	 = new TitledBorder (Translatrix.getTranslationString("AddressImportPanel.FileBorderTitle"));

	m_FilePanel = new JPanel ();
	m_FilePanel.setOpaque(false);
	m_FilePanel.setLayout(l_Layout);
	m_FilePanel.setBorder(m_FileBorder);
	
	m_UpdateFileCaption = new JLabel ();
	m_UpdateFileCaption.setText(Translatrix.getTranslationString("AddressImportPanel.UpdateFileCaption"));
	m_UpdateFileCaption.setForeground(GECAMedColors.c_LabelColor);
	l_CaptionFont    = m_UpdateFileCaption.getFont();
	m_UpdateFileCaption.setFont (l_CaptionFont.deriveFont((float)(l_CaptionFont.getSize() * 0.75)));

	m_AddressUpdateFile = new FileSelectorPanel (MainFrame.getInstance(),c_AddressUpdateFile,FileSelectorPanel.c_ForLoading);
	m_AddressUpdateFile.setOpaque (false);
	m_AddressUpdateFile.addPropertyChangeListener(this);
	
	m_Import = new JButton ();
	m_Import.setEnabled(false);
	m_Import.setIcon(AddressModuleLoader.getIconResource("import_small.png"));
	m_Import.setText (Translatrix.getTranslationString("AddressImportPanel.ImportButton"));
	m_Import.addActionListener(this);
	
	// retrieve the server dir to directly open the address update folder
	try {
	    ListManagerInterface listManager = (ListManagerInterface) ManagerFactory.getRemote(ListManagerBean.class);
	    String dir = (String) listManager.getServerInfos().get(ListManagerInterface.GECAMED_DIR);
	    m_Logger.info("install dir is: " + dir);
	    m_Logger.info("setting dir: " + new File(dir, "install/address_updates"));
	    m_AddressUpdateFile.forgetFile();
	    m_AddressUpdateFile.setDir(new File(dir, "install/address_updates"));	    
	} catch (Exception e) {
	    e.printStackTrace();
	}

	m_FilePanel.add (m_UpdateFileCaption, l_Constraints.xywh(4, 2, 1, 3));
	m_FilePanel.add (m_AddressUpdateFile, l_Constraints.xywh(6, 2, 1, 1));
	m_FilePanel.add (m_Import, 			  l_Constraints.xywh(6, 4, 1, 1));
	
	
	//=======================================================================
	//= Assemble Locality Panel
	//=======================================================================
	
	l_Layout = new FormLayout(c_LocalityColumns, c_LocalityRows);

	m_LocalityBorder = new TitledBorder (Translatrix.getTranslationString("AddressImportPanel.LocalityBorderTitle"));

	m_LocalityPanel = new JPanel ();
	m_LocalityPanel.setOpaque(false);
	m_LocalityPanel.setLayout(l_Layout);
	m_LocalityPanel.setBorder(m_LocalityBorder);
	

	m_LocalitiesCaption = new JLabel ();
	m_LocalitiesCaption.setForeground(GECAMedColors.c_LabelColor);
	l_CaptionFont    = m_LocalitiesCaption.getFont();
	m_LocalitiesCaption.setFont (l_CaptionFont.deriveFont((float)(l_CaptionFont.getSize() * 0.75)));
	
	m_Localities = new LocalityListBox ();
	m_Localities.setColumnWidths(new int[] {20, 70, 70, 70});
	m_Localities.addMouseListener(new MouseAdapter() {
		@Override
		public void mouseClicked(MouseEvent e) {
			if (e.getClickCount() >= 2) {
				Locality l = m_Localities.getSelectedLocality();
				if (l != null) {
					editLocality(l);
				}
			}
		}
	});
	
	m_AddLocalities = new JButton ();
	m_AddLocalities.setIcon(GECAMedModule.getSmallIcon(GECAMedIconNames.ADD_LINE));
	m_AddLocalities.setText (Translatrix.getTranslationString("core.add"));
	m_AddLocalities.addActionListener(this);
	
	m_EditLocalities = new JButton ();
	m_EditLocalities.setIcon(GECAMedModule.getSmallIcon(GECAMedIconNames.EDIT));
	m_EditLocalities.setText (Translatrix.getTranslationString("core.edit"));
	m_EditLocalities.addActionListener(this);

	
	
	
	m_LocalityPanel.add (m_Localities, 		  l_Constraints.xywh(2, 2, 9, 1));
	m_LocalityPanel.add (m_AddLocalities,  l_Constraints.xywh(8, 4, 1, 1));
	m_LocalityPanel.add (m_EditLocalities,  l_Constraints.xywh(10, 4, 1, 1));
	
	//=======================================================================
	//= Assemble ZIP Panel
	//=======================================================================
	
	l_Layout = new FormLayout(c_ZIPColumns, c_ZIPRows);

	m_ZIPBorder = new TitledBorder (Translatrix.getTranslationString("AddressImportPanel.ZIPBorderTitle"));

	m_ZIPPanel = new JPanel ();
	m_ZIPPanel.setOpaque(false);
	m_ZIPPanel.setLayout(l_Layout);
	m_ZIPPanel.setBorder(m_ZIPBorder);
		
	m_ZIPsCaption = new JLabel ();
	m_ZIPsCaption.setForeground(GECAMedColors.c_LabelColor);
	l_CaptionFont    = m_ZIPsCaption.getFont();
	m_ZIPsCaption.setFont (l_CaptionFont.deriveFont((float)(l_CaptionFont.getSize() * 0.75)));

	m_ZIPs = new ZIPListBox ();
	m_ZIPs.setColumnWidths(new int[] {20, 30, 100, 100, 15,15,15});
	m_ZIPs.addMouseListener(new MouseAdapter() {

		@Override
		public void mouseClicked(MouseEvent e) {
			if (e.getClickCount() >= 2) {
				Zip l = m_ZIPs.getSelectedZip();
				if (l != null) {
					editZip(l);
				}
			}
		}
	});

	m_AddZIPs = new JButton ();
	m_AddZIPs.setIcon(GECAMedModule.getSmallIcon(GECAMedIconNames.ADD_LINE));
	m_AddZIPs.setText (Translatrix.getTranslationString("core.add"));
	m_AddZIPs.addActionListener(this);

	m_EditZIPs = new JButton ();
	m_EditZIPs.setIcon(GECAMedModule.getSmallIcon(GECAMedIconNames.EDIT));
	m_EditZIPs.setText (Translatrix.getTranslationString("core.edit"));
	m_EditZIPs.addActionListener(this);

	m_ZIPPanel.add (m_ZIPs, 		  	l_Constraints.xywh(2, 2, 9, 1));
	m_ZIPPanel.add (m_AddZIPs,  		l_Constraints.xywh(8, 4, 1, 1));
	m_ZIPPanel.add (m_EditZIPs,  		l_Constraints.xywh(10, 4, 1, 1));
	
	l_Layout = new FormLayout(c_Columns, c_Rows);
	this.setLayout(l_Layout);
	
	this.add(m_FilePanel,		l_Constraints.xywh(2, 2, 1, 1));
	this.add(m_LocalityPanel,	l_Constraints.xywh(2, 4, 1, 1));
	this.add(m_ZIPPanel,		l_Constraints.xywh(2, 6, 1, 1));
	
	m_ProgressDialog = new ProgressDialog ();
	
	
	localityEditDialog 	= new LocalityEditDialog(MainFrame.getInstance());
	zipEditDialog 		= new ZipEditDialog(MainFrame.getInstance());
	
	
	//Disable buttons if in demo mode
	if (GECAMedUtils.isDemo() && !MainFrame.isAdmin()) {
	   	// disables all tabs
		m_AddLocalities.setEnabled(false);
		m_EditLocalities.setEnabled(false);
		m_AddZIPs.setEnabled(false);
		m_EditZIPs.setEnabled(false);
	} else {
		m_AddLocalities.setEnabled(true);
		m_EditLocalities.setEnabled(true);
		m_AddZIPs.setEnabled(true);
		m_EditZIPs.setEnabled(true);
	}
	
	
	
	new Thread() {
		public void run() {
			reloadLocalityPanel();
			reloadZIPPanel();					
		}
	}.start();
	
	}
	
//---------------------------------------------------------------------------
//***************************************************************************
//* Interface Getters                                                       *
//***************************************************************************
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
/**
 * The private getInvoiceInterface returns an instance of the InvoiceBean
 * session bean. On the first call, the InvoiceBean will actualy be looked up
 * via JNDI. Once it has been found, the reference to the bean will be stored
 * in a private data member. Doing so avoids JNDI lookups on later calls.
 * @return an instance of the InvoiceBean session bean.
 */
//---------------------------------------------------------------------------

private AddressManagerInterface getAddressManagerInterface ()
	{
	if (m_AddressManagerInterface != null) return m_AddressManagerInterface;

		m_AddressManagerInterface = (AddressManagerInterface) ManagerFactory.getRemote(AddressManagerBean.class);

	return m_AddressManagerInterface;
	}

/**
 * The private getInvoiceInterface returns an instance of the InvoiceBean
 * session bean. On the first call, the InvoiceBean will actualy be looked up
 * via JNDI. Once it has been found, the reference to the bean will be stored
 * in a private data member. Doing so avoids JNDI lookups on later calls.
 * @return an instance of the InvoiceBean session bean.
 */
//---------------------------------------------------------------------------

private AddressImportInterface getAddressImportInterface ()
	{
	if (m_AddressImportInterface != null) return m_AddressImportInterface;

		m_AddressImportInterface = (AddressImportInterface) ManagerFactory.getRemote(AddressImportBean.class);

	return m_AddressImportInterface;
	}

//---------------------------------------------------------------------------
//***************************************************************************
//* Primitives                                                              *
//***************************************************************************
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------


//---------------------------------------------------------------------------

public void reloadLocalityPanel ()
	{
	List<Locality> l_LocalityList = GECAMedLists.getListReference(Locality.class);

	
	TreeSet<Locality> ts = new TreeSet<Locality>(new Comparator<Locality>(){
		public int compare(Locality o1, Locality o2) {
	    		try {
	    			return o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase());				
	    		} catch (Exception e) {
	    			return 0;
	    		}
	    }
	});
	ts.addAll(l_LocalityList);
	
	m_Localities.setLocalitys(ts);
//	m_Localities.packColumns();
	}

//---------------------------------------------------------------------------

public void reloadZIPPanel ()
	{
	List<Zip> l_ZipList = GECAMedLists.getListReference(Zip.class);
	
	Collections.sort(l_ZipList, new Comparator<Zip>(){
		public int compare(Zip o1, Zip o2) {
			try {
				return o1.getZip().compareTo(o2.getZip());				
			} catch (Exception e) {
				return 0;
			}
		}
	});
//	ts.addAll(l_ZipList);
	
	m_ZIPs.setZIPs(l_ZipList);
	m_ZIPs.packColumns();
	}


//---------------------------------------------------------------------------

private void importAddresses(File p_File) {
	
	boolean success = processUpdateFile(p_File);
	
	if (success) {
		m_Localities.removeAllLocalitys();
		processLocalities();
		success = importLocalities();
	}
	
	if (success) {
		reloadLocalityPanel();
		
		m_ZIPs.removeAllZIPs();
		processZIPCodes();
		importZIPs();
		reloadZIPPanel();
	}
	
}

//---------------------------------------------------------------------------

private boolean processUpdateFile (File p_File)
	{
	AddressImportInterface	l_AddressImportInterface;
	boolean					l_Success = false;
	
	l_AddressImportInterface = this.getAddressImportInterface();
	if (l_AddressImportInterface == null) return l_Success;
		
	m_Updater = new AddressUpdater ();
	m_Updater.addProgressListener(this);
	
	try {
		m_Updater.setMunicipalities 	(l_AddressImportInterface.getAllMunicipalities());
		m_Updater.setLocalities 		(l_AddressImportInterface.getAllLocalities());
		m_Updater.setZips 				(l_AddressImportInterface.getAllZips());

		m_Updater.extractUpdateFiles (p_File);
		
		m_Updater.processAliasesFile();
		m_Updater.processLocalityFile();
		l_Success = true;
		}
	catch (Exception p_Exception)
		{
		m_Logger.log(Level.ERROR, "Failed to process update file", p_Exception);
		}	
	
	return l_Success;
	}

//---------------------------------------------------------------------------

private boolean importLocalities ()
	{
	AddressImportInterface	l_AddressImportInterface;
	Collection <Locality>	l_NewLocalities;
	Iterator   <Locality>	l_LocalityIterator;	
	Locality				l_Locality;	

	boolean					l_Success = false;
	
	if (m_Updater == null) return l_Success;

	l_AddressImportInterface = this.getAddressImportInterface();
	if (l_AddressImportInterface == null) return l_Success;

	try	{
		l_NewLocalities = m_Updater.getNewLocalities();
		if (l_NewLocalities != null)
			{
			l_LocalityIterator = l_NewLocalities.iterator();
			while (l_LocalityIterator.hasNext())
				{
				l_Locality = l_LocalityIterator.next();
				l_Locality = l_AddressImportInterface.saveLocality (l_Locality);
				}
			
			m_Updater.setLocalities (l_AddressImportInterface.getAllLocalities());
			m_Updater.rebuildLookupTables();
			
			GECAMedLists.resetListAndNotifyListener(Locality.class);
			
			l_Success = true;
			}
		}
	catch (Exception p_Exception)
		{
		m_Logger.log(Level.ERROR, "Failed to import new localities", p_Exception);
		}	
		
	return l_Success;
	}


//---------------------------------------------------------------------------

private synchronized void processLocalities ()
	{
	String []		l_Filler;
	
	m_NumberOfLines = Long.valueOf(m_Updater.getNumberOfLocalityFileLines());
		
	m_ProgressDialog.setCancelable(false);
	m_ProgressDialog.setProgressBarMode (ProgressDialog.c_Determined);
	m_ProgressDialog.setProgressBarSpan (1, m_NumberOfLines.intValue());

	m_ProgressDialog.setTitle("AddressImportPanel.ProcessingLocalitiesTitle");
	m_ProgressDialog.setMessage("AddressImportPanel.ProcessingLocalitiesMessage",null);
	m_ProgressDialog.pack();
	
	MainFrame.showDialogCentered (m_ProgressDialog);
	
	l_Filler = new String [1];
		
	l_Filler [0] = m_NumberOfLines.toString();
					
	m_ProgressDialog.setTask("AddressImportPanel.ProcessingLocalitiesTask", l_Filler);
	
	m_Updater.processLocalityFile();
	
	m_ProgressDialog.setVisible(false);
	m_ProgressDialog.reset();
	}

//---------------------------------------------------------------------------

private synchronized void processZIPCodes ()
	{
	String []		l_Filler;
	
	m_NumberOfLines = Long.valueOf(m_Updater.getNumberOfZIPCodeFileLines());
		
	m_ProgressDialog.setCancelable(false);
	m_ProgressDialog.setProgressBarMode (ProgressDialog.c_Determined);
	m_ProgressDialog.setProgressBarSpan (1, m_NumberOfLines.intValue());

	m_ProgressDialog.setTitle("AddressImportPanel.ProcessingZIPsTitle");
	m_ProgressDialog.setMessage("AddressImportPanel.ProcessingZIPsMessage",null);
	m_ProgressDialog.pack();
	
	MainFrame.showDialogCentered (m_ProgressDialog);
	
	l_Filler = new String [1];
		
	l_Filler [0] = m_NumberOfLines.toString();
					
	m_ProgressDialog.setTask("AddressImportPanel.ProcessingZIPsTask", l_Filler);
	
	m_Updater.processZIPCodeFile();
	
	m_ProgressDialog.setVisible(false);
	m_ProgressDialog.reset();
	}

//---------------------------------------------------------------------------

private synchronized void importZIPs ()
	{
	AddressImportInterface	l_AddressImportInterface;
	Collection <Zip>		l_ZIPs;
	Iterator   <Zip>		l_ZIPIterator;	
	Zip						l_ZIP;	
	String[]				l_Filler;
	ImportProgress			l_Progress;
	int						l_Count;
	
	if (m_Updater == null) return;

	l_AddressImportInterface = this.getAddressImportInterface();
	if (l_AddressImportInterface == null) return;
	
	l_Progress = new ImportProgress (this,0,"");
	
	try	{
		l_ZIPs = m_Updater.getNewZips();
		if (l_ZIPs != null)
			{
			m_NumberOfLines = Integer.valueOf(l_ZIPs.size()).longValue();
			
			m_ProgressDialog.setCancelable(false);
			m_ProgressDialog.setProgressBarMode (ProgressDialog.c_Determined);
			m_ProgressDialog.setProgressBarSpan (1, m_NumberOfLines.intValue());

			m_ProgressDialog.setTitle("AddressImportPanel.ImportingZIPsTitle");
			m_ProgressDialog.setMessage("AddressImportPanel.ImportingZIPsMessage",null);
			m_ProgressDialog.pack();
			
			MainFrame.showDialogCentered (m_ProgressDialog);
			
			l_Filler = new String [1];	
			l_Filler [0] = Integer.valueOf(l_ZIPs.size()).toString();
			l_Count = 0;
			
			m_ProgressDialog.setTask("AddressImportPanel.AddingNewZIPsTask", l_Filler);
			
			l_ZIPIterator = l_ZIPs.iterator();
			while (l_ZIPIterator.hasNext())
				{
				l_ZIP = l_ZIPIterator.next();
				l_ZIP = l_AddressImportInterface.saveZip (l_ZIP);
				l_Progress.setLineNumber(l_Count++);
				this.progressChanged(l_Progress);
				}
			}
	
		l_ZIPs = m_Updater.getObsoleteZips();
		if (l_ZIPs != null)
			{
			m_NumberOfLines = Integer.valueOf(l_ZIPs.size()).longValue();
			m_ProgressDialog.setProgress (0);
			m_ProgressDialog.setProgressBarSpan (1, m_NumberOfLines.intValue());
			
			l_Filler = new String [1];	
			l_Filler [0] = Integer.valueOf(l_ZIPs.size()).toString();
			l_Count = 0;
			
			m_ProgressDialog.setTask("AddressImportPanel.RemovingObsoleteZIPsTask", l_Filler);
	
			l_ZIPIterator = l_ZIPs.iterator();
			while (l_ZIPIterator.hasNext())
				{
				l_ZIP = l_ZIPIterator.next();
				l_AddressImportInterface.deleteZip(l_ZIP);
				l_Progress.setLineNumber(l_Count++);
				this.progressChanged(l_Progress);
				}
			}
		
		GECAMedLists.resetListAndNotifyListener(Zip.class);
		m_ProgressDialog.setVisible(false);
		}		
	catch (Exception p_Exception)
		{
		m_Logger.log(Level.ERROR, "Failed to import ZIPs", p_Exception);
		}	
	}


//---------------------------------------------------------------------------

public void propertyChange (PropertyChangeEvent p_Event) 
	{
	File 					l_File;
	
	if (p_Event.getSource() == m_AddressUpdateFile)
		{
		if (p_Event.getPropertyName().equals(FileSelectorPanel.c_FileSelectionChanged))
			{
			l_File = (File) p_Event.getNewValue();
			m_Import.setEnabled(l_File.exists());
			}				
		}
	}

//---------------------------------------------------------------------------

public void actionPerformed(ActionEvent p_Event) 
	{
	if (p_Event.getSource().equals(m_EditLocalities)) {
		Locality l = m_Localities.getSelectedLocality();
		if (l != null) {
			editLocality(l);
		}
	} else if (p_Event.getSource().equals(m_AddLocalities)) {
		editLocality(new Locality());
		
	} else if (p_Event.getSource().equals(m_EditZIPs)) {
		Zip l = m_ZIPs.getSelectedZip();
		if (l != null) {
			editZip(l);
		}
	} else if (p_Event.getSource().equals(m_AddZIPs)) {
		editZip(new Zip());
	} else if (p_Event.getSource().equals(this.m_Import)) {
		new Thread() {
			public void run() {
				try {
					MainFrame.getInstance().setWaitCursor(true);
					importAddresses(new File(m_AddressUpdateFile.getFilePath()));
				} catch (Exception e) {
					logger.error("Error importing Addresses", e);
				} finally {
					MainFrame.getInstance().setWaitCursor(false);
				}
				
				
			}
		}.start();
	}

	}

//---------------------------------------------------------------------------

private void editLocality(Locality l) {
	try {
		if (localityEditDialog.editLocality(l) == JOptionPane.OK_OPTION) {
			l = localityEditDialog.getLocality();
			l = getAddressImportInterface().saveLocality(l);
			GECAMedLists.resetListAndNotifyListener(Locality.class);
			reloadLocalityPanel();					
		}
	} catch (Exception e) {
		logger.error("error Editing Locality!" , e);
	}
}

//---------------------------------------------------------------------------

private void editZip(Zip l) {
	try {
		if (zipEditDialog.editZip(l) == JOptionPane.OK_OPTION) {
			l = zipEditDialog.getZip();
			l = getAddressImportInterface().saveZip(l);
			GECAMedLists.resetListAndNotifyListener(Zip.class);
			reloadZIPPanel();				
		}
	} catch (Exception e) {
		logger.error("error Editing Zip!" , e);
	}
}

public void progressChanged(ProgressEvent p_Event) 
	{
	ImportProgress  l_Event;
	String []		l_Filler;
	
	if (	(p_Event.getSource().equals (m_Updater))
		 || (p_Event.getSource().equals (this)))
		{
		l_Event = (ImportProgress)p_Event;
		l_Filler = new String [2];
		
		l_Filler [0] = Long.valueOf (l_Event.getLineNumber()).toString();
		l_Filler [1] = (m_NumberOfLines != null)?m_NumberOfLines.toString():"0";

		switch (m_Operation)
			{
			case c_ProcessLocalities: 
				
				m_ProgressDialog.setProgress (Long.valueOf (l_Event.getLineNumber()).intValue(),
								  							"AddressImportPanel.ZIPProcessingProgress",
								  							l_Filler);
	  			break;
			
			case c_ProcessZIPs: 		 
	  			
				m_ProgressDialog.setProgress (Long.valueOf (l_Event.getLineNumber()).intValue(),
								  							"AddressImportPanel.LocalityProcessingProgress",
								  							l_Filler);
				break;
			
			case c_ImportZIPs: 		 
	  			
				m_ProgressDialog.setProgress (Long.valueOf (l_Event.getLineNumber()).intValue(),
								  							"AddressImportPanel.ZIPImportProgress",
								  							l_Filler);
				break;
			}
		}
	}

//---------------------------------------------------------------------------

public void relocalize() 
	{
	if (m_FileBorder != null)
		m_FileBorder.setTitle (Translatrix.getTranslationString("AddressImportPanel.FileBorderTitle"));
	
	if (m_UpdateFileCaption != null)
		m_UpdateFileCaption.setText(Translatrix.getTranslationString("AddressImportPanel.UpdateFileCaption"));

	if (m_LocalityBorder != null)
		m_LocalityBorder.setTitle (Translatrix.getTranslationString("AddressImportPanel.LocalityBorderTitle"));

	if (m_LocalitiesCaption != null)
		m_LocalitiesCaption.setText(Translatrix.getTranslationString("AddressImportPanel.LocalitiesCaption"));
	
	if (m_ZIPBorder != null)
		m_ZIPBorder.setTitle (Translatrix.getTranslationString("AddressImportPanel.ZIPBorderTitle"));
	}


public void enablePanel(boolean b) {
	this.m_AddressUpdateFile.setEditable(b);
}

//---------------------------------------------------------------------------
//***************************************************************************
//* End of Class                                                            *
//***************************************************************************
//---------------------------------------------------------------------------
}
