
/**
 *
 * applet to display demonstration Java program source code
 *
 * Written by: Roger Garside
 *
 * First Written: 2/Feb/97
 * Last Rewritten: 30/May/97
 *
 */

import java.applet.* ;
import java.awt.* ;
import java.awt.event.* ;
import java.io.* ;
import java.net.* ;
import java.util.* ;

public class Chapter20n2 extends Applet implements ActionListener
    {
    // picture elements
    private Label label ;
    private TextArea area ;
    private Button main, chap, prog ;

    private static final int MAX_NO_OF_PROGRAMS = 200 ;

    // list of all programs available
    private int noOfPrograms ;
    private ProgramDetails[] progs = new ProgramDetails[MAX_NO_OF_PROGRAMS] ;
    private String indexString ;
    // list of programs for current chapter
    private int noOfPrograms1 ;
    private ProgramDetails[] progs1 = new ProgramDetails[MAX_NO_OF_PROGRAMS] ;
    private String indexString1 ;

    /**
     *
     * init
     *
     */

    public void init()
	{
	readIndex() ;

	setLayout(new BorderLayout()) ;
        setBackground(Color.green) ;

        label = new Label("Main Index", Label.CENTER) ;
	add("North", label) ;

	// set up the text area
	area = new TextArea(20, 80) ;
	area.setText(indexString) ;
	add("Center", area) ;

	// set up the buttons
	Panel p = new Panel() ;
	p.setLayout(new FlowLayout()) ;
	main = new Button("Main Index") ;
	p.add(main) ;
        main.addActionListener(this) ;
	main.setEnabled(false) ;
	chap = new Button("Chapter") ;
	p.add(chap) ;
        chap.addActionListener(this) ;
	chap.setEnabled(true) ;
	prog = new Button("Program") ;
	p.add(prog) ;
        prog.addActionListener(this) ;
	prog.setEnabled(false) ;
	add("South", p) ;
	} // end of method init

    /**
     *
     * readIndex
     *
     */

    private void readIndex()
	{
	try {
	    // access the file "programList"
	    URL index = new URL(getDocumentBase(), "programList") ;
	    BufferedReader s1 = new BufferedReader(new
				InputStreamReader(index.openStream())) ;

	    // read the program list into the array "prog"
	    // and the chapter names into the string "indexString"
	    noOfPrograms = 0 ;
	    indexString = "" ;
	    String previousFirst = "" ;
	    while (true)
	        {
		String line = s1.readLine() ;
		if (line == null)
		    break ;
		StringTokenizer st = new StringTokenizer(line, "/") ;
		String first = st.nextToken() ;
		String second = st.nextToken() ;
		if (noOfPrograms >= MAX_NO_OF_PROGRAMS)
		    {
		    System.err.println("too many programs") ;
		    System.exit(1) ;
		    }
                progs[noOfPrograms] = new ProgramDetails(first, second) ;
                if (!first.equals(previousFirst))
		    {
		    if (indexString.length() != 0)
		        indexString += '\n' ;
                    progs[noOfPrograms].start = indexString.length() ;
		    indexString += first ;
                    progs[noOfPrograms].finish = indexString.length() ;
		    }
                previousFirst = first ;
		noOfPrograms++ ;
		}
            }
        catch (IOException e)
	    {
	    System.err.println("ERROR: " + e) ;
	    }
	} // end of method readIndex


    /**
     *
     * actionPerformed
     *
     */

    public void actionPerformed(ActionEvent event)
        {
	// deal with "Main Index" button
	if (event.getSource() == main)
	    {
	    label.setText("Main Index") ;
	    area.setText(indexString) ;
	    main.setEnabled(false) ;
	    chap.setEnabled(true) ;
	    prog.setEnabled(false) ;
	    }
	// deal with "Chapter" button
	else if (event.getSource() == chap)
	    {
	    // get the line selected
	    int start = area.getSelectionStart() ;
	    int finish = area.getSelectionEnd() ;
	    // look for the entry in the "prog" array
	    int i = 0 ;
	    while ((i < noOfPrograms) && (start > progs[i].finish))
		i++ ;
            if (i == noOfPrograms)
		System.err.println("no chapter selected") ;
	    else
		{
		// extract a list of programs in this chapter into the
		// array "prog1" and the string "indexString1"
		String thisChap = progs[i].first ;
		noOfPrograms1 = 0 ;
		indexString1 = "" ;
		for (int j = 0 ; j < noOfPrograms ; j++)
		    if (progs[j].first.equals(thisChap))
			{
			progs1[noOfPrograms1] = new
				ProgramDetails(thisChap, progs[j].second) ;
			if (indexString1.length() != 0)
			    indexString1 += '\n' ;
                        progs1[noOfPrograms1].start = indexString1.length() ;
                        indexString1 += progs[j].second ;
                        progs1[noOfPrograms1].finish = indexString1.length() ;
			noOfPrograms1++ ;
			}
                label.setText(thisChap) ;
                area.setText(indexString1) ;
		main.setEnabled(true) ;
		chap.setEnabled(false) ;
		prog.setEnabled(true) ;
		}
	    }
	// deal with "Program" button
	else if (event.getSource() == prog)
	    {
	    // get the line selected
	    int start = area.getSelectionStart() ;
	    int finish = area.getSelectionEnd() ;
	    // look for the entry in the "prog1" array
	    int i = 0 ;
	    while ((i < noOfPrograms1) && (start > progs1[i].finish))
		i++ ;
            if (i == noOfPrograms1)
		System.err.println("no program selected") ;
	    else
		{
		// access the appropriate file of source text
		String thisProg = progs1[i].second ;
	        try {
	            URL t = new URL(getDocumentBase(), thisProg) ;
	            BufferedReader s1 = new BufferedReader(new
				InputStreamReader(t.openStream())) ;
		    String textString = "" ;
	            while (true)
	                {
		        String line = s1.readLine() ;
		        if (line == null)
		            break ;
                        if (textString.length() != 0)
			    textString += '\n' ;
                        textString += line ;
			}
                    label.setText(thisProg) ;
                    area.setText(textString) ;
		    main.setEnabled(true) ;
		    chap.setEnabled(false) ;
		    prog.setEnabled(false) ;
		    }
                catch (IOException e1)
	            {
	            System.err.println("ERROR: " + e1) ;
	            }
		}
	    }
        } // end of method actionPerformed
    } // end of class Chapter20n2

class ProgramDetails
    {
    String first, second ;
    int start, finish ;

    /**
     * constructor
     */
    public ProgramDetails(String f, String s)
        {
        first = f ;
        second = s ;
        start = -1 ;
        finish = -1 ;
        } // end of constructor method
    } // end of class ProgramDetails


