import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

class Memo implements Serializable
{
    private int day, month, year, hour, min;
    private String title, text;
    private transient int id; //should not save as may need new
    private static transient int id_index; //should not be saved as reindex

    public Memo ( ) 
    {
	this("Untitled", null );
    }

    public Memo( String n_title, String n_text )
    {
	Calendar cal = new GregorianCalendar();
	Date currentTime = new Date();
	cal.setTime( currentTime );
	
	day = cal.get(Calendar.DAY_OF_MONTH);
	month = cal.get(Calendar.MONTH);
	year = cal.get(Calendar.YEAR);
	hour = cal.get(Calendar.HOUR);
	min = cal.get(Calendar.MINUTE);
	id = id_index++; //get new id and incriment index
	title = n_title;
	text = n_text;
    }
    public Memo( int D, int Mo, int Y, int H, int Mi, String Ti, String Tx )
    {
	day = D;
	month = Mo;
	year = Y;
	hour = H;
	min = Mi;
	title = Ti;
	text = Tx;
	id = id_index++;
    }

    public Memo( Memo m )
    {
	this( m.day, m.month, m.year, m.hour, m.min, m.title, m.text );
    }

    public void diagnostic ()
    {
	System.out.print( "Start of memo id: " + id + "\n" );
	System.out.print( "created on : " );
	System.out.print( day + "\\" + month + "\\" + year );
	System.out.print( "---" + hour + ":" + min + "\n" );
	System.out.print( "Title: " + title + "\n" );
	System.out.print( "Text: " + text + "\n" );
    }
    void set_title ( String new_title )
    {
	title = new_title;
    }

    String get_title ( )
    {
	return title;
    }

    void set_text(String new_text)
    {
	text = new_text;
    }

    String get_text ( )
    {
	return text;
    }

    void print ()
    {
	System.out.println("Title: " + title );
	System.out.println("Notes: " + text );
    }

}//end of class Memo

class PIM_IO
{
    private ObjectInputStream i_stream;
    private ObjectOutputStream o_stream;
    private boolean reader;
    
    PIM_IO ()
    //default constructor created out of habbit
    {}

    public void openForRead ( String filename )
    //open a file for reading 
    {
	reader = true;
	try {
	    i_stream = new ObjectInputStream ( new FileInputStream( filename) );
	}catch ( IOException e ) {
	    System.out.println( e.getMessage() );
	}
    }

    public void openForRead()
    {
	String filename=null;
	BufferedReader console = new BufferedReader( new InputStreamReader( System.in) );
	try {
		System.out.print( "Enter the name of the file to read: ");
		filename = console.readLine().trim();
		this.openForRead( filename );
	}catch (IOException e ) {
	    System.out.println( e.getMessage() );
	}
    }

    public void openForWrite( String filename )
    {
	reader = false;
	try {
	    o_stream = new ObjectOutputStream ( new FileOutputStream( filename) );
	} catch (IOException e ) {
	    System.out.println( e.getMessage() );
	}
    }
    
    public void openForWrite()
    {
	String filename = null;
	BufferedReader console = new BufferedReader( new InputStreamReader( System.in) );
	try {
	    System.out.print( "Enter the name of the file to write: ");
	    filename = console.readLine().trim();
	    this.openForWrite( filename );
	} catch (IOException e ) {
	    System.out.println( e.getMessage() );
	}
    }

    public Memo get_memo ( )
    {
	try {
	    return (Memo)i_stream.readObject();
	} catch (EOFException e) {
	    return null;
	} catch (IOException e) {
	    System.out.println(e.getMessage() );
	} catch (ClassNotFoundException e ) {
	    System.out.println( e.getMessage() );
	}
	return null;
    }

    public void put_memo( Memo m )
    {
	try {
	    o_stream.writeObject( m );
	} catch (IOException e) {
	    System.out.println(e.getMessage() );
	}
    }

    public void close()
    {
	try {
	    if ( reader )
		i_stream.close();
	    else {
		o_stream.flush();
		o_stream.close();
	    }
	}catch ( IOException e ) {
	    System.out.println( e.getMessage() );
	    e.printStackTrace();
	}
    }
} //end of PIM_IO

class PIM_GUI extends JFrame
{
    JButton IO_b, Edit_b, Delete_b, Create_b, Receive_b, Send_b, Quit_b;
    Memo []memolist = new Memo[10];
    DefaultListModel title_model;
    JList title_list;
    int count=0;
    //listSize tracks the size of the list (total number of slots)
    //count tracks the number of spots in memolist with valid data

    public PIM_GUI()
    {
	setTitle("Main Window");
	Container cp = getContentPane();
	JPanel jp_west = new JPanel();
	JPanel jp_east = new JPanel();
	ButtonHandler bh = new ButtonHandler();
	IO_b = new JButton( "File Operations" );
	IO_b.addActionListener ( bh );
	Create_b = new JButton( "Create" );
	Create_b.addActionListener( bh );
	Edit_b = new JButton( "Edit" );
	Edit_b.addActionListener( bh );
	Delete_b = new JButton( "Delete" );
	Delete_b.addActionListener( bh );
	Receive_b = new JButton("Receive");
	Receive_b.addActionListener ( bh );
	Send_b = new JButton ( "Send" );
	Send_b.addActionListener( bh );
	Quit_b = new JButton("Quit");
	Quit_b.addActionListener ( bh );

	jp_west.setLayout( new GridLayout( 8,1 ) );
	jp_west.add( new JLabel ("Select an Operation") );
	jp_west.add( Create_b );
	jp_west.add( Edit_b );
	jp_west.add( Delete_b );
	jp_west.add( IO_b );
	jp_west.add( Send_b );
	jp_west.add( Receive_b );
	jp_west.add( Quit_b );

	title_model = new DefaultListModel();
	title_list = new JList ( title_model );
	title_list.setVisibleRowCount( 15 );
	title_list.setFixedCellWidth ( 20 );
	title_list.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
	JScrollPane scroll_list = new JScrollPane( title_list );

	jp_east.setLayout( new BorderLayout() );
	jp_east.add( new JLabel ("Select a Memo" ), "Center" );
	jp_east.add( scroll_list, "South" );

	cp.add(jp_west, "West" );
	cp.add(jp_east, "East" );
	addWindowListener( new exitWindow () );


    }
    
    class ButtonHandler implements ActionListener
    {
	public void actionPerformed( ActionEvent evt )
	{
	    Object ob = evt.getSource();
	    if ( ob == Quit_b ) 
		System.exit(0);
	    else if ( ob == IO_b )
		IO_Window();
	    else if ( ob == Receive_b || ob==Send_b )
		Network_Ops( ob );
	    else if ( ob == Create_b )
		Create_Window();
	    else if ( ob == Delete_b ) 
		Remove_Memo ( title_list.getSelectedIndex() );
	    else if ( ob == Edit_b ) 
		Edit_Window ( title_list.getSelectedIndex() );
	}

    } //end of ButtonHandler

    private void Edit_Window( final int target )
    {
	final JFrame E_W = new JFrame("Edit a Memo");
	
	Container cp = E_W.getContentPane();
	JPanel jp_center = new JPanel();
	JPanel jp_south = new JPanel();
	jp_center.setLayout( new GridLayout(2,2) );
	jp_south.setLayout( new BorderLayout() );
	final JButton done_b = new JButton("Done");
	final JButton cancel_b = new JButton( "Cancel" );
	final JTextField jt_title = new JTextField( memolist[target].get_title() );
	final JTextField jt_text = new JTextField( memolist[target].get_text() );
	
	jp_center.add( new JLabel( "Memo Title" ) );
	jp_center.add( jt_title );
	jp_center.add( new JLabel( "Memo Text" ) );
	jp_center.add( jt_text );

	class EW_BH implements ActionListener
	{
	    public void actionPerformed ( ActionEvent evt )
	    {
		Object ob = evt.getSource();
		if ( ob == done_b ) {
		    memolist[target].set_title( jt_title.getText() );
		    memolist[target].set_text( jt_text.getText() );
		    synchList( target );
		}
		E_W.dispose();
	    }
	}


	jp_south.add( done_b, "West" );
	jp_south.add( cancel_b, "East" );
	
	cancel_b.addActionListener( new EW_BH() );
	done_b.addActionListener( new EW_BH() );
	cp.add(jp_center, "Center");
	cp.add(jp_south, "South");
	E_W.setSize( 400, 150 );
	E_W.setVisible(true);
    }

    private void Create_Window()
    {
	final JFrame C_W = new JFrame("Create a New Memo");
	Container cp = C_W.getContentPane();
	JPanel jp_center = new JPanel();
	JPanel jp_south = new JPanel();
	jp_center.setLayout( new GridLayout(2,2) );
	jp_south.setLayout( new BorderLayout() );
	final JButton done_b = new JButton("Done");
	final JButton cancel_b = new JButton( "Cancel" );
	final JTextField jt_title = new JTextField();
	final JTextField jt_text = new JTextField();
	
	jp_center.add( new JLabel( "Memo Title" ) );
	jp_center.add( jt_title );
	jp_center.add( new JLabel( "Memo Text" ) );
	jp_center.add( jt_text );

	class CW_BH implements ActionListener
	{
	    public void actionPerformed ( ActionEvent evt )
	    {
		Object ob = evt.getSource();
		if ( ob == done_b ) {
		    Memo temp = new Memo( jt_title.getText(), jt_text.getText() );
		    Add_Memo( temp );
		}
		C_W.dispose();
	    }
	}


	jp_south.add( done_b, "West" );
	jp_south.add( cancel_b, "East" );
	
	cancel_b.addActionListener( new CW_BH() );
	done_b.addActionListener( new CW_BH() );
	cp.add(jp_center, "Center");
	cp.add(jp_south, "South");
	C_W.setSize( 400, 150 );
	C_W.setVisible(true);
    }

  
    private void IO_Window()
    {

	final JButton Read, Write, Cancel;
	final JTextField jl_filename = new JTextField(null);
	JPanel b_panel = new JPanel();
	final JFrame IO_W = new JFrame();

	b_panel.add( Read=new JButton("Read") );
	b_panel.add( Write=new JButton("Write" ) );
	b_panel.add( Cancel=new JButton( "Cancel" ) );

	class IO_bh implements ActionListener
	{
	    public void actionPerformed( ActionEvent e )
	    {
		Object ob = e.getSource();    
		if ( ob == Read )
		    read_file();
		else if ( ob == Write )
		    write_file();

		IO_W.dispose();
	    }

	    private void read_file() 
	    {
		if ( jl_filename.getText() != null ) {
		    PIM_IO p_io = new PIM_IO();
		    p_io.openForRead( jl_filename.getText() );
		    Memo temp = p_io.get_memo();
		    while ( temp != null ) {
			Add_Memo( new Memo(temp) );
			temp = p_io.get_memo();
		    }
		    p_io.close();
		}
	    }
	    private void write_file()
	    {
		if ( jl_filename.getText() != null && count > 0) {
		    PIM_IO p_io = new PIM_IO();
		    p_io.openForWrite( jl_filename.getText() );
		    for ( int i=0; i< count; i++ )
			p_io.put_memo( memolist[i] );
		    p_io.close();
		}
		
	    }
	}

	Cancel.addActionListener( new IO_bh() );
	Read.addActionListener( new IO_bh() );
	Write.addActionListener( new IO_bh() );
	Container cp = IO_W.getContentPane();	
	cp.add(new JLabel ("Enter a file to read or write to"), "North");
	cp.add( jl_filename, "Center" );
	cp.add( b_panel, "South");

	IO_W.setTitle("IO Operations");
	IO_W.setSize(300, 90);
	IO_W.setLocation(300, 400);
	IO_W.setVisible(true);


    }

    private void Network_Ops( Object ob )
    {
	JFrame netWindow = new JFrame();
	Container cp = netWindow.getContentPane();
	if ( ob == Send_b ) {
	    netWindow.setTitle ("Sending Memo Window");
	    cp.add( new JLabel ("Sending not enabled") );
	}
	else {
	    netWindow.setTitle ("Listening Server");
	    cp.add( new JLabel ("Server not implimented") );
	}
	netWindow.setSize(400, 100 );
	netWindow.setLocation( 300, 300 );
	netWindow.setVisible(true);
    }


    class exitWindow extends WindowAdapter
    {
	public void windowClosing( WindowEvent e )
	{
	    System.exit(0);
	}
    }//end of exitWindow

    private void Add_Memo ( Memo m )
    //handles additions to the memo list
    {
	if ( count == memolist.length ) {
	    //need to grow the list
	    Memo []tempList = new Memo[count + 10];
	    for (int i=0; i < count; i++ )
		tempList[i] = memolist[i];
	    memolist = tempList;
	}
	memolist[count] = m;
	title_model.addElement(m.get_title());
	count++;
    }
    
    private void Remove_Memo ( int target )
    //handles removing a memo
    {
	if ( target > -1 && target < count ) {
	    for ( int i=target; i < count-1; i++ )
		memolist[i] = memolist[i+1];
	    count--;

	    title_model.remove( target );
	}
    }


    private void synchList( )
    {
	title_model.removeAllElements();
	for ( int i=0; i<count; i++ ) 
	    title_model.set(i, memolist[i].get_title() );
    }
    
    private void synchList( int target )
    {
	title_model.set(target, memolist[target].get_title() );
    }


} //end PIM_GUI




public class Project4
{
    public static void main( String []args )
    {

	JFrame jf = new PIM_GUI();
	jf.setSize(300, 300);
	jf.setVisible(true);
	
    } 
}











