/*******************************************************************************
 * 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
 *******************************************************************************/
/*
 * Author: Johannes Hermen Tudor/Santec
 * Mail: johannes.hermen@tudor.lu
 * Created: May 20, 2005
 *
 */
package lu.tudor.santec.gecamed.icd10.gui;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;

import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.i18n.Translatrix;

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


/**
 * This Class is a JPanel that is able to retrieve the ICD10 Codes from the
 * World Health Organisation's website and show the HTML results
 *
 * @author Johannes Hermen johannes.hermen(at)tudor.lu Tudor/Santec
 *
 */
public class ICD10ViewerModule extends GECAMedModule implements ActionListener
{
    //~ Static fields/initializers =============================================

    /**
     * The name of the module 
     */
    public static final String MODULE_NAME = "ICD 10";
	
    private static final long serialVersionUID = 1L;
    private static final String LINESPACE = "1dlu"; //$NON-NLS-1$
    private static final String COLUMNSPACE = "2dlu"; //$NON-NLS-1$
    private static final String SEARCH_STRING = "http://www3.who.int/icd/vol1htm2003/search.cfm?searchtype=1&SuchCode=&searchtext=";
    
    private static ImageIcon iconSearch = new ImageIcon(ICD10ViewerModule.class.getResource ("resources/search.png"));
    private static ImageIcon iconBack = new ImageIcon(ICD10ViewerModule.class.getResource ("resources/back.png"));
    private static ImageIcon iconForeward = new ImageIcon(ICD10ViewerModule.class.getResource ("resources/forward.png"));
    private static ImageIcon iconHome = new ImageIcon(ICD10ViewerModule.class.getResource ("resources/home.png"));
    
    //~ Instance fields ========================================================

    private JButton searchButton;
    private JEditorPane editorPane;
    private JLabel status;
    private JTextField searchField;
    private Vector history = new Vector();
    private int historyIndex = 0;
    private boolean hasBeenBuild = false;

    //~ Constructors ===========================================================
    /**
     * creates a new Viewer Panel
     * @param mainFrame
     */
    public ICD10ViewerModule()
    {
    	super(MODULE_NAME, iconSearch, Color.LIGHT_GRAY);
    	this.setOpaque(false);
    }

    //~ Methods ================================================================
    /**
     * creates a new Action to go back one page
     * @return the Action
     */
    public AbstractAction getActionBack()
    {
        return new AbstractAction("",
            iconBack) {
				private static final long serialVersionUID = 1L;

				public void actionPerformed(ActionEvent e)
                {
                    if ((historyIndex - 1) < 0) {
                        status.setText("First Page!");
                        return;
                    }
                    status.setText("Fetching Page....");
                    status.validate();
                    try {
                        showPage((URL) history.get(historyIndex - 1));
                        historyIndex--;
                    } catch (Exception e3) {
                        e3.printStackTrace();
                    }
                }
            };
    }

    /**
     * creates a new Action to go forard one page
     * @return the Action
     */
    public AbstractAction getActionForward()
    {
        return new AbstractAction("",
            iconForeward) {
				private static final long serialVersionUID = 1L;

				public void actionPerformed(ActionEvent e)
                {
                    if ((historyIndex + 1) >= history.size()) {
                        status.setText("Last Page!");
                        return;
                    }
                    status.setText("Fetching Page....");
                    status.validate();
                    try {
                        showPage((URL) history.get(historyIndex + 1));
                        historyIndex++;
                    } catch (Exception e3) {
                        //                        e3.printStackTrace();
                    }
                }
            };
    }

    //    /**
    //     * creates a new Action for searching the icd10 database
    //     * @return the Action
    //     */
    //    public AbstractAction getActionSearchCode()
    //    {
    //        return new AbstractAction(Translatrix.getTranslationString(""), //$NON-NLS-1$
    //            IconBuilder.createMiniImageIcon(IconBuilder.SEARCH)) {
    //                public void actionPerformed(ActionEvent e)
    //                {
    //                    URL helpURL = null;
    //                    try {
    //                        helpURL = new URL(SEARCH_STRING_CODE +
    //                                searchICDField.getText());
    //                        System.out.println(helpURL.toString());
    //                    } catch (MalformedURLException e1) {
    //                        e1.printStackTrace();
    //                    }
    //                    add2history(helpURL);
    //                    showPage(helpURL);
    //                }
    //            };
    //    }


    /**
     * creates a new Action for loading the startpage
     * @return the Action
     */
    public AbstractAction getActionHome()
    {
        return new AbstractAction("",
            iconHome) {
				private static final long serialVersionUID = 1L;

				public void actionPerformed(ActionEvent e)
                {
                    try {
                        showPage(new URL("file:resources/ICD10Viewer.html"));
                    } catch (Exception e3) {
                        e3.printStackTrace();
                    }
                }
            };
    }


    /**
     * creates a new Action for searching the icd10 database
     * @return the Action
     */
    public AbstractAction getActionSearch()
    {
        return new AbstractAction(Translatrix.getTranslationString(""), //$NON-NLS-1$
            iconSearch) {
				private static final long serialVersionUID = 1L;

				public void actionPerformed(ActionEvent e)
                {
                    URL helpURL = null;
                    status.setText("Fetching Page....");
                    status.validate();
                    try {
                        helpURL = new URL(SEARCH_STRING +
                                searchField.getText());
                    } catch (MalformedURLException e1) {
                        e1.printStackTrace();
                    }
                    add2history(helpURL);
                    showPage(helpURL);
                }
            };
    }

    /* (non-Javadoc)
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */
    public void actionPerformed(ActionEvent e)
    {
        if (e.getSource().equals(this.searchField)) {
            URL helpURL = null;
            try {
                helpURL = new URL(SEARCH_STRING + searchField.getText());
            } catch (MalformedURLException e1) {
                e1.printStackTrace();
            }
            add2history(helpURL);
            showPage(helpURL);
        }
    }


    /**
     * adds the specified URL to the History
     * @param url
     */
    @SuppressWarnings("unchecked")
	public void add2history(URL url)
    {
        history.add(url);
        historyIndex = history.size() - 1;
    }


    /**
     * loads the specified URL to the panel
     * @param url
     */
    public void showPage(URL url)
    {
        this.status.setText("Fetching Page....");
        this.status.validate();
        this.mainFrame.setWaitCursor(true);
        if (url != null) {
            try {
                editorPane.setPage(url);
                this.status.setText("Page Loaded!");
            } catch (Exception e) {
                this.status.setText("Page Could Not Be Loaded!");
                //e.printStackTrace();
            }
        } else {
            this.status.setText("Page Not Found!");
        }
        this.mainFrame.setWaitCursor(false);
    }

    /**
     * adds the components to the panel
     */
    private void buildPanel()
    {
        initComponents();

        JPanel content = new JPanel();
        content.setOpaque(false);
        // build Layout
        FormLayout layout = new FormLayout(COLUMNSPACE + ", pref, " +
                COLUMNSPACE + ", fill:pref:grow, " + COLUMNSPACE + ", pref, " +
                COLUMNSPACE + ", 40dlu, " + COLUMNSPACE + ", pref, " +
                COLUMNSPACE,
                LINESPACE + ", pref, " + LINESPACE + ", fill:pref:grow, " +
                LINESPACE + ", 10dlu, " + LINESPACE);
        content.setLayout(layout);
        CellConstraints cc = new CellConstraints();
        JToolBar toolBar = new JToolBar();
        toolBar.setFloatable(false);
        toolBar.add(this.getActionBack());
        toolBar.add(this.getActionForward());
        toolBar.add(this.getActionHome());
        toolBar.setOpaque(false);
        // add Search
        content.add(toolBar, cc.xyw(2, 2, 1));
        content.add(this.searchField, cc.xyw(4, 2, 6));
        content.add(this.searchButton, cc.xyw(10, 2, 1));

        //        this.add(new NamedComponent("Search by ICD", this.searchICDField), cc.xyw(8, 2, 1));
        //        this.add(this.searchICDButton, cc.xyw(10, 2, 1));
        // add Pane
        JScrollPane editorScrollPane = new JScrollPane(editorPane);
        editorScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        editorScrollPane.setPreferredSize(new Dimension(250, 145));
        content.add(editorScrollPane, cc.xyw(2, 4, 10));
        content.add(this.status, cc.xyw(2, 6, 10));
        
        this.setContentPanel(content);
        this.hasBeenBuild = true;
    }

    /**
     * initializes the Components
     */
    private void initComponents()
    {
        searchField = new JTextField();
        searchField.addActionListener(this);
        searchField.setPreferredSize(new Dimension(0, 22));
        searchButton = new JButton(getActionSearch());

        //        searchICDField = new JTextField();
        //        searchICDField.setPreferredSize(new Dimension(0, 22));
        //        searchICDButton = new JButton(getActionSearchCode());
        status = new JLabel("");
        status.setOpaque(false);
        editorPane = new JEditorPane();
        editorPane.addHyperlinkListener(new SimpleLinkListener(editorPane,
                searchField, status));

        //        editorPane.setEditorKitForContentType("text/html", new PatchedHTMLEditorKit());
        editorPane.setEditable(false);
    }

    //~ Inner Classes ==========================================================
    /**
     * listener to make links in the HTML clickable
     * @author Johannes Hermen johannes.hermen(at)tudor.lu Tudor/Santec
     *
     */
    public class SimpleLinkListener implements HyperlinkListener
    {
        //~ Instance fields ====================================================

        private JEditorPane pane; // The pane we're using to display HTML
        private JLabel statusBar; // An option label for showing where
        public SimpleLinkListener(JEditorPane jep, JTextField jtf, JLabel jl)
        {
            pane = jep;
            statusBar = jl;
        }

        //~ Methods ============================================================

        public void hyperlinkUpdate(HyperlinkEvent he)
        {
            // We'll keep some basic debuggin information in here so you can
            // verify our new editor kit is working.
            HyperlinkEvent.EventType type = he.getEventType();

            // Ok.  Decide which event we got...
            if (type == HyperlinkEvent.EventType.ENTERED) {
                // Enter event.  Go the the "hand" cursor and fill in the status bar
                pane.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
                statusBar.setText(he.getURL().toString());
            } else if (type == HyperlinkEvent.EventType.EXITED) {
                // Exit event.  Go back to the default cursor and clear the status bar
                pane.setCursor(Cursor.getDefaultCursor());
                statusBar.setText(" ");
            } else {
                try {
                    add2history(he.getURL());
                    showPage(he.getURL());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

	@Override
	public void afterShowup() {
		this.searchField.setSelectionEnd(this.searchField.getText().length());
		this.searchField.setSelectionStart(0);
		this.searchField.setCaretPosition(0);
		this.searchField.requestFocus();
	}

	/* (non-Javadoc)
	 * @see lu.tudor.santec.gecamed.core.gui.GECAMedModule#preparetoShowup()
	 */
	@Override
	public void preparetoShowup() {
		if (this.hasBeenBuild) {
			return;
		} else {
			MainFrame.getInstance().setWaitCursor(true);
	        this.buildPanel();
	        this.showPage(this.getClass().getResource("resources/ICD10Viewer.html"));
	        MainFrame.getInstance().setWaitCursor(false);
		}
	}
	
	
}
