/*
   Tamot --- Task Modelling Editor
   Copyright (C) 2000 Commonwealth Scientific and Industrial Research Organisation
   (CSIRO), Australia. All rights reserved. 

   The Software, owned by CSIRO Australia, has been developed by the CSIRO 
   Intelligent Interactive Technology group. 
   For more information, please see http://www.cmis.csiro.au/iit/.

   Redistribution in source and binary forms, with or without modification, are not permitted.

   The Software is a beta-test version for internal research and evaluation purposes 
   by the Licensee. The Software is still at a development stage. 
   It has not undergone complete testing and may have inherent errors,
   bugs or deficiencies that can affect the operation of the Software. 

   We encourage your feedback and suggestions. Any bugs / suggestions found please email to
   Shijian.Lu@cmis.csiro.au and Thomas.Lo@cmis.csiro.au. 

   After you have signed the Beta-Test Software License Agreement with the CSIRO,
   CSIRO grants you a non-exclusive, non-transferable license to use it only for your 
   personal, non-commercial and lawful end use. Implied licenses are negated. 

   Warranty Disclaimer : 

   CSIRO supplies the Software on an "as is" basis and makes no warranties that use of
   the Software by the Licensee will not infringe any third party’s 
   Intellectual Property Rights nor that the Software will be of merchantable quality,
   or suitable for a particular purpose. CSIRO excludes all terms, conditions and
   warranties implied by custom, the general law or statute in relation to the
   Software.
*/

package taskModellingTool;

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.net.URL;
import javax.swing.text.html.HTMLEditorKit;
import java.util.*;


public class TVFrame extends JFrame {
    private JButton backButton;
    private JButton forwardButton;
    
    private JTextField urlField;
    private JEditorPane editorPane;
    private JLabel statusBar;
    
    private int pageCounter = 0;
    private TreeMap addressTreeMap = new TreeMap();    // Integer pageCounter (key), String html address (value)
    
    
    public TVFrame(String name, String htmlPathName) {
        super(name);
        
        String homeAddress = "file:///" + htmlPathName;
            
        // Set up our basic screen components, the editor pane, the
        // text field for URLs, and the label for status and link information
        JPanel buttonPanel = getButtonPanel();

        JPanel urlPanel = new JPanel();
        urlPanel.setLayout(new BorderLayout());
        
        urlPanel.add(buttonPanel, BorderLayout.WEST);
        
        urlField = new JTextField(homeAddress);
        urlPanel.add(urlField, BorderLayout.CENTER);
        
        statusBar = new JLabel(" ");
            
        editorPane = new JEditorPane();
        editorPane.setEditable(false);
        
        HTMLEditorKit htmlEditorKit = new HTMLEditorKit();
        
        editorPane.setEditorKitForContentType("text/html", htmlEditorKit);

        displayNewUrlPage(homeAddress);
        
        JScrollPane scrollPane = new JScrollPane(editorPane);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        
        // and get the GUI components onto our content pane
        getContentPane().add(urlPanel, BorderLayout.NORTH);
        getContentPane().add(scrollPane, BorderLayout.CENTER);
        getContentPane().add(statusBar, BorderLayout.SOUTH);
        
        int FRAME_INSET = 35;
        
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds(FRAME_INSET,FRAME_INSET,
            screenSize.width-FRAME_INSET*2,
            screenSize.height-FRAME_INSET*2);
        
        // and last but not least, hook up our event handlers
        // allow user to type the url and then press 'Enter' to try to display the HTML
        urlField.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                String address = actionEvent.getActionCommand();

                displayNewUrlPage(address);
                updateButtonStatus();
            }
        });
        
        editorPane.addHyperlinkListener(new TVLinkListener(this, editorPane, statusBar)); 
        updateButtonStatus();
    }

    private void displayNewUrlPage(String address) {
        try {
            URL url = new URL(address);
    
            displayNewUrlPage(url);
        }
        catch (Exception e) {
            statusBar.setText("Could not open the specified page : "+address);
        }
    }

    public void displayNewUrlPage(URL url) {
        try {
            String address = url.toString();
            
            //TMUtility.display("displayNewUrlPage : url",address);
            
            editorPane.setPage(url);
            
            if (urlField != null) {
                urlField.setText(address);
            }
            
            clearHistoryFromPageCounterOnwards();
            putToAddressTreeMap(address);
        }
        catch(Exception e) {
            statusBar.setText("Could not open page - "+url);
        }
    }

    private JPanel getButtonPanel() {
        JPanel result = new JPanel();
        
        result.setLayout(new FlowLayout(FlowLayout.LEADING));
        
        backButton    = new JButton("  Back  ");
        forwardButton = new JButton("Forward");
        
        result.add(backButton);
        result.add(forwardButton);

        result.add(new JLabel("    Address : "));
        
        addBackButtonListener(backButton);
        addForwardButtonListener(forwardButton);
        
        return result;
    }
    
    private void displayOldUrlPage(String address) {
        try {
            URL url = new URL(address);
    
            displayOldUrlPage(url);
        }
        catch (Exception e) {
            statusBar.setText("Could not open the specified page : "+address);
        }
    }

    public void displayOldUrlPage(URL url) {
        try {
            String address = url.toString();
            
            //TMUtility.display("displayOldUrlPage : url",address);
            
            editorPane.setPage(url);
            
            if (urlField != null) {
                urlField.setText(address);
            }
            
            //displayAddressTreeMapContents();
        }
        catch(Exception e) {
            statusBar.setText("Could not open page - "+url);
        }
    }

    private void addBackButtonListener(JButton backButton) {
        backButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                if (pageCounter > 1) {
                    pageCounter--;
                    String address = getUrlFromAddressTreeMap();
                    
                    displayOldUrlPage(address);
                    
                    updateButtonStatus();
                }
            }
        });
    }

    private void addForwardButtonListener(JButton forwardButton) {
        forwardButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                int lastPageCounter = getLastPageCounter();
                
                if (pageCounter < lastPageCounter) {
                    pageCounter++;
                    String address = getUrlFromAddressTreeMap();
                    
                    displayOldUrlPage(address);
                    
                    updateButtonStatus();
                }
            }
        });
    }

    public void updateButtonStatus() {
        int lastPageCounter = getLastPageCounter();
        
        if (pageCounter <= 1)
            backButton.setEnabled(false);
        else
            backButton.setEnabled(true);
        
        if (pageCounter >= lastPageCounter)
            forwardButton.setEnabled(false);
        else
            forwardButton.setEnabled(true);
    }
    
    private int getLastPageCounter() {
        int result = 0;
        
        if (addressTreeMap.size() == 0) return result;
        
        Integer iPageCounter = (Integer) addressTreeMap.lastKey();
        
        result = iPageCounter.intValue();
        
        return result;
    }
    
    private String getUrlFromAddressTreeMap() {
        String result = null;
        
        Integer iPageCounter = new Integer(pageCounter);
        
        if (addressTreeMap.containsKey(iPageCounter)) {
            result = (String) addressTreeMap.get(iPageCounter);
        }
        
        return result;
    }
    
    private void clearHistoryFromPageCounterOnwards() {
        int lastPageCounter = getLastPageCounter();
        
        for (int i=pageCounter+1; i<= lastPageCounter; i++) {
            Integer iPageCounter = new Integer(i);
            
            if (addressTreeMap.containsKey(iPageCounter)) {
                addressTreeMap.remove(iPageCounter);
            }
        }
    }
    
    private void putToAddressTreeMap(String url) {
        pageCounter++;
        
        Integer iPageCounter = new Integer(pageCounter);
        
        addressTreeMap.put(iPageCounter,url);
        
        displayAddressTreeMapContents();
    }

    private void displayAddressTreeMapContents() {
        TMUtility.displayLine(2);
        
        TMUtility.display("pageCounter = "+pageCounter);
        
        for (Iterator i=(addressTreeMap.keySet()).iterator();i.hasNext();) {
             Integer iPageCounter = (Integer) i.next();
             String address = (String) addressTreeMap.get(iPageCounter);
             
             TMUtility.display(iPageCounter+" : ["+address+"]");
        }
    }
    
}