/*
 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0, which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.io.*;
import javax.activation.*;

public class JAFApp extends Frame implements WindowListener, ItemListener, ActionListener {

    // UI stuff...
    private GridBagLayout gridbag = null;
    private GridBagLayout panel_gb = null;
    private List file_list = null;
    private Panel results_panel = null;
    private Label f_title = null;
    private Label f_name_label = null;
    private Label type_label = null;
    private Label type_title = null;
    private Button launch_button = null;
    private Choice verb_choice = null;
    // File stuff...
    private File _file = null;
    // private FileDataSource fds[] = null;
    private DataHandler dh[] = null;

    private boolean debug = false;
    //    private 
    ///////////////////////////////////////////////////////////////////////
    // ctor
    public JAFApp(String title)
	{
	   super(title);
	   initMe();
	}

    public JAFApp()
	{
	    super();
	    initMe();
	}
    
    ///////////////////////////////////////////////////////////////////////
    // initME -- init the UI
    private void initMe()
	{
	    Font label_font = new Font("Default", Font.PLAIN, 12);
	    Font title_font = new Font("Default", Font.BOLD, 12);

	    gridbag = new GridBagLayout();
	    setLayout(gridbag);
	    
	    this.setBackground(Color.white);

	    // results panel create
	    results_panel = new Panel();
	    panel_gb = new GridBagLayout();
	    results_panel.setLayout(panel_gb);
	    results_panel.setBackground(Color.lightGray);
	    addGridComponent(this,
			     results_panel,
			     gridbag,
			     0,0,
			     1,1,
			     1,0 );

	    // file name label
	    f_title = new Label("File Name:");
	    f_title.setBackground(Color.lightGray);
	    f_title.setAlignment(Label.RIGHT);
	    f_title.setFont(title_font);	    
	    addGridComponent(results_panel,
			     f_title,
			     panel_gb,
			     0, 0,
			     1, 1,
			     5, 100);

	    // file name label
	    f_name_label = new Label("<none selected>");
	    f_name_label.setBackground(Color.lightGray);
	    f_name_label.setAlignment(Label.LEFT);
	    f_name_label.setFont(label_font);
	    addGridComponent(results_panel,
			     f_name_label,
			     panel_gb,
			     1, 0,
			     1, 1,
			     15, 100);
	    
	    	    // file name label
	    f_title = new Label("MIME Type:");
	    f_title.setBackground(Color.lightGray);
	    f_title.setAlignment(Label.RIGHT);
	    f_title.setFont(title_font);	    
	    addGridComponent(results_panel,
			     f_title,
			     panel_gb,
			     2, 0,
			     1, 1,
			     5, 100);

	    // type_label
	    type_label = new Label("<no type>");
	    type_label.setBackground(Color.lightGray);
	    type_label.setAlignment(Label.LEFT);
	    type_label.setFont(label_font);
	    addGridComponent(results_panel,
			     type_label,
			     panel_gb,
			     3,0,
			     1,1,
			     10, 100);

	    // launch button
	    launch_button = new Button("Launch!");
	    launch_button.setEnabled( false );
	    launch_button.setBackground(Color.red);
	    launch_button.setFont(title_font);
	    addGridComponent(results_panel,
			     launch_button,
			     panel_gb,
			     4,0,
			     1,1,
			     5, 100);
	    
	    // verb popup
	    verb_choice = new Choice();
	    verb_choice.setEnabled( false );
	    verb_choice.setFont(label_font);
	    verb_choice.add("<empty>");
	    addGridComponent(results_panel,
			     verb_choice,
			     panel_gb,
			     5,0,
			     1,1,
			     10, 100);

	    // file list
	    file_list = new List();
	    file_list.setBackground(Color.white);
	    file_list.setFont(label_font);
	    addGridComponent(this,
			     file_list,
			     gridbag,
			     0,1,
			     1, 2,
			     1,1);

	    this.invalidate();

	    // set up events
	    this.addWindowListener(this);
	    file_list.addItemListener(this);
	    launch_button.addActionListener(this);

	}

    ////////////////////////////////////////////////////////////////////////
    /**
     * adds a component to our gridbag layout
     */
    private void addGridComponent(Container cont, 
				  Component comp,
				  GridBagLayout mygb,
				  int gridx,
				  int gridy, 
				  int gridw,
				  int gridh,
				  int weightx,
				  int weighty)
	{ 
	    GridBagConstraints c = new GridBagConstraints(); 
	    c.gridx = gridx; 
	    c.gridy = gridy; 
	    c.gridwidth = gridw; 
	    c.gridheight = gridh; 
	    c.fill = GridBagConstraints.BOTH;
	    c.weighty = weighty;
	    c.weightx = weightx;
	    c.anchor =  GridBagConstraints.CENTER;
	    mygb.setConstraints(comp, c); 
	    cont.add(comp); 
	}

    ///////////////////////////////////////////////////////////////////////
    // setFile - sets the file/directory for this frame at startup usually
    //
    public void setFile( File file )
	{
	    _file = file;
	    int i;
	    MailcapCommandMap cmdmap = 
		(MailcapCommandMap)CommandMap.getDefaultCommandMap();
	    cmdmap.addMailcap("application/x-int;      jaf.viewers.IntViewer");

	    if(_file.isFile())
		{
		    dh = new DataHandler[1];
		    dh[0] = new DataHandler(new FileDataSource( _file ));

		    file_list.add( dh[0].getName() );
		}
	    else if( _file.isDirectory() )
		{
		    String files[] = _file.list();
		    MimetypesFileTypeMap map = new MimetypesFileTypeMap();
		    map.addMimeTypes("text/java java\n");
		    FileTypeMap.setDefaultFileTypeMap(map);
		    dh = new DataHandler[ files.length ];
		    // iterate through the list and make fds
		    for( i = 0; i < files.length; i++)
			{


			    if(debug)
				System.out.println(files[i]);

			    dh[i] = new  DataHandler(
					   new FileDataSource( _file.getAbsolutePath() +
							       _file.separator +  
							       files[i] )
					   );
			    dh[i].setCommandMap(cmdmap);

// 			    try {
// 				((FileDataSource)dh[i].getDataSource()).addMimeTypes("text/plain java\n");
// 			    } catch(IOException e){ System.out.println(e); }
			    file_list.add(dh[i].getName());
			}
		    System.out.println("number of files: " + files.length +
				       " read : " + i);

		}

	}
    /////////////////***ACTION LISTENER***///////////////////////
    // is called when a monkey (user) presses the launch button
    public void actionPerformed(ActionEvent evt)
	{
	    Object source = evt.getSource();
	    int index = file_list.getSelectedIndex();
	    
	    // make sure it's the launch button and that
	    // a list item is selected...
	    if(source == launch_button && index > -1){
		CommandInfo cmds[] = null;
		String mimeType = dh[index].getContentType();
		
		if(debug)
		    System.out.println("Finding...");
		
		// get the available commands for this type
		cmds = dh[index].getPreferredCommands();
		
		// if we actually got some back...
		if(cmds.length > 0){ 
		    CompViewer cont = null;
		    Object my_bean = null;
		    // take the first one
		    if(debug)
			System.out.println("Launching...");
		    
		    // get the first one
		    my_bean = dh[index].getBean( cmds[verb_choice.getSelectedIndex()] );
		    
			    // if it isn't a CommandObject we still
			    // have to give it it's data...
// 			    if(!(my_bean instanceof javax.activation.CommandObject))
// 				{
// 				    System.out.println("WHOOOAAA!");
// 				    if(my_bean instanceof 
// 				       java.io.Externalizable)
		
// 					{
// 					    try
// 						{
//                 	     ((Externalizable)my_bean).readExternal(
// 						new ObjectInputStream( 
// 						   dh[index].getInputStream() 
// 						   )
// 						);
// 						} catch(Exception e)
// 						    {
// 				  System.out.println("There was a problem reading the Externalized Data in the viewer bean : " + e);
// 						    }
// 					}
// 				}
		    if(debug)
			System.out.println("GOTTA BEAN!: " + 
					   my_bean.getClass().getName() );
			    // create a new bean container
		    cont = new CompViewer( "JAF Component" );
		    cont.setBean( (Component) my_bean);
		    cont.show();
		}
	    }
	}
    /////////////////***ITEM LISTENER***/////////////////////////
    public void itemStateChanged(ItemEvent evt)
	{
	    Integer id = (Integer)evt.getItem();

	    if(evt.getStateChange() == ItemEvent.SELECTED)
		{
		    // get the content type from the data handler...
		    String mime_type = dh[id.intValue()].getContentType();
		    // set the state in the info dlog:
		    f_name_label.setText(dh[id.intValue()].getName());
		    
		    // set the field in the UI and enable launch button
		    if(mime_type != null)
			{
			    CommandInfo cmds[] = null;
			    // set the text label
			    type_label.setText(mime_type);

			    // check to see if any commands are available
			    cmds = dh[id.intValue()].getPreferredCommands();
			    if(cmds != null && cmds.length > 0) // we got a command!
				{
				    launch_button.setEnabled( true );
				    verb_choice.setEnabled( true );
				    launch_button.setBackground( Color.green );

				    verb_choice.removeAll();
				    for(int i = 0; i < cmds.length; i++)
					{
					    //		    verb_choice.addItem(cmds[i].getBeanDescriptor().getName());
					    verb_choice.addItem(cmds[i].getCommandName());
					}
				}
			    else
				{
				    launch_button.setEnabled( false );
				    verb_choice.setEnabled( false );
				    launch_button.setBackground( Color.red );
				}
			    
			}
		    else
			{
			    // set label to be unknown and launch button off!
			    type_label.setText("<unknown>");
			    launch_button.setEnabled( false );
			    launch_button.setBackground( Color.red );
			}
		    
		}
	}
    /////////////////***WINDOW LISTENER***////////////////////////
    public void windowOpened(WindowEvent e){}
    public void windowClosing(WindowEvent e)
	{
	    System.exit(0); // quit
	}
    public void windowClosed(WindowEvent e){}
    public void windowIconified(WindowEvent e){}
    public void windowDeiconified(WindowEvent e){}
    public void windowActivated(WindowEvent e){}
    public void windowDeactivated(WindowEvent e){}
	    
    ///////////////////////////////////////////////////////////////////////
    // main
    public static void main(String args[])
	{
	    JAFApp appFrame = new JAFApp("JAF Testing Application");
	    appFrame.setSize(600, 400);
	    appFrame.show();

	    // set the directory
	    if(args.length == 0)
		{
		    appFrame.setFile( new File("."));
		}
	    else
		{
		    appFrame.setFile( new File(args[0]) );
		}
	}

	    
}
