package W3C.PICS;

import java.awt.*;
import java.io.*;
/**
 * The main window for creating Labels and Filters
 * @author Ching Law
 */

public class PICSWindow extends Frame {

    public PICSWindow() {
	super("PICS");

	//{{INIT_MENUS
	MenuBar mb = new MenuBar();
	fileMenu = new Menu("&File");
	fileMenu.add(new MenuItem("Open Rating Service [Label]"));
	fileMenu.add(new MenuItem("Open Rating Service [Filter]"));
	fileMenu.addSeparator();
	fileMenu.add(new MenuItem("&Save Label"));
	fileMenu.add(new MenuItem("Save Label &As..."));
	fileMenu.add(new MenuItem("Save Filter"));
	fileMenu.add(new MenuItem("Save Filter As..."));
	fileMenu.add(new MenuItem("Load Filter"));
	fileMenu.add(new MenuItem("&Close"));
	fileMenu.addSeparator();
	fileMenu.add(new MenuItem("E&xit"));
	mb.add(fileMenu);
	menu1 = new Menu("&Options");
	menu1.add(new MenuItem("Show &Label"));
	menu1.add(new MenuItem("Service Info..."));
	MenuItem tempMenuItem;
	menu1.add(tempMenuItem = new CheckboxMenuItem("List for Labels"));
	((CheckboxMenuItem) tempMenuItem).setState(true);
	menu1.add(new CheckboxMenuItem("Simple Filtering"));
	mb.add(menu1);
	helpMenu = new Menu("&Help");
	helpMenu.add(new MenuItem("&About..."));
	mb.add(helpMenu);
	setMenuBar(mb);
	//}}

	//{{INIT_CONTROLS
//	setLayout(null);
	addNotify();
	resize(insets().left + insets().right + 352, insets().top + insets().bottom + 254);
	//}}

    setResizable(false);
	welcomeMessage();
	show();

    }

    public synchronized void show() {
	super.show();

    }

    public boolean handleEvent(Event event) {

	if (event.id == Event.WINDOW_DESTROY) {
	    hide();
	    dispose();
	    System.exit(0);
	    return true;
	}
	return super.handleEvent(event);
    }

    public boolean action(Event event, Object arg) {
	if (event.target instanceof MenuItem) {
	    String label = (String) arg;
	    if (label.equalsIgnoreCase("Load Filter")) {
	        selectedLoadFilter();
	        return true;
	    } else if (label.equalsIgnoreCase("Simple Filtering")) {
	        selectedSimpleFiltering();
	        return true;
	    } else if (label.equalsIgnoreCase("Save Filter As...")) {
	        selectedSaveFilterAs();
	        return true;
	    } else if (label.equalsIgnoreCase("Save Filter")) {
	        selectedSaveFilter();
	        return true;
	    } else if (label.equalsIgnoreCase("List for Labels")) {
	        selectedListForLabels();
	        return true;
	    } else if (label.equalsIgnoreCase("Open Rating Service [Filter]")) {
	        selectedOpenRatingServiceFilter();
	        return true;
	    } else if (label.equalsIgnoreCase("Open Rating Service [Label]")) {
	        selectedOpenRatingServiceLabel();
	        return true;
	    } else if (label.equalsIgnoreCase("Show &Label")) {
	        selectedShowLabel();
	        return true;
	    } else if (label.equalsIgnoreCase("Save Label &As...")) {
	        selectedSaveLabelAs();
	        return true;
	    } else if (label.equalsIgnoreCase("&Close")) {
	        selectedClose();
	        return true;
	    } else if (label.equalsIgnoreCase("&Save Label")) {
	        selectedSaveLabel();
	        return true;
	    } else if (label.equalsIgnoreCase("Service Info...")) {
	        selectedServiceInfo();
	        return true;
	    } else if (label.equalsIgnoreCase("&About...")) {
		selectedAbout();
		return true;
	    } else if (label.equalsIgnoreCase("E&xit")) {
		selectedExit();
		return true;
	    }
	}
	return super.action(event, arg);
    }

    public static void main(String args[]) {
	PICSWindow PW=new PICSWindow();
    PW.resize(550,650);
    PW.setBackground(Color.lightGray);
    }

    //{{DECLARE_MENUS
    Menu fileMenu;
    Menu menu1;
    Menu helpMenu;
    //}}

    //{{DECLARE_CONTROLS
    //}}


/*    private void selectedOpenService()
    {
	 FileDialog fd=new FileDialog(this, "Open...",FileDialog.LOAD);
	 fd.setFile("*.rat");
     fd.show();

     String filename=fd.getFile();
     if (filename!=null)
        openService(filename,Category.U_RATING);
    }
*/
    /**
    Called when Open Service Rating menu item is selected. A file dialog is popped up
    to select the Service Rating file. The user interface for label creation is then
    constructed according to the service file.
    */
    private void openService(String filename,int type)
    {
      FileInputStream fis;

       try
         {fis=new FileInputStream(filename);}
        catch (FileNotFoundException e)
        {
        System.out.println("File not found");
        return;
        }
        catch (IOException e)
        {
            System.out.println("IO Exception");
            return;
        }

      try
      {
       Ser=new Service(fis);
       Ser.setListForLabels(ListForLabels);

      }
       catch (PICSException e)
      {
        try
        {fis.close();} catch (IOException ei) {System.out.println("Closing error");}

        System.out.println("PICS Service Parsing Error:");
        System.out.println(e);
      }
      catch (IOException e)
      {System.out.println("IO error");}
       // Put the Interface Widgets of the New Service
         removeAll();
         Ser.newInterface(this,type,ListForLabels,SimpleFiltering);
         setTitle("PICS " + Ser.getName() + " - [" + filename + "]");
         show();
    } //openService



    void selectedExit() {
	QuitBox theQuitBox;
	theQuitBox = new QuitBox(this);
	theQuitBox.show();
    }


    void selectedAbout() {
	AboutBox theAboutBox;
	theAboutBox = new AboutBox(this);
	theAboutBox.show();
    }

    void selectedServiceInfo() {
     if (Ser!=null)
     {
        ServiceInfoBox theServiceInfoBox;
        theServiceInfoBox = new ServiceInfoBox(this,Ser.getName(),Ser.getDescription(),Ser.getRatingsystem(),Ser.getRatingservice());
        theServiceInfoBox.show();
     }
    }
    private void selectedSaveLabel() {
      if (Ser!=null && Ser.getUType()==Service.U_LABEL)
        {
         if (labelfilename==null)
                selectedSaveLabelAs();
         else SaveLabel(labelfilename);
        }
    }
    private void selectedClose() {
        setTitle("PICS");
        removeAll();
        labelfilename=null;
        filterfilename=null;
        Ser=null;
    }

    private void selectedSaveLabelAs() {
	 if (Ser==null || Ser.getUType()!=Service.U_LABEL)
	    return;

	 FileDialog fd=new FileDialog(this, "Save As...",FileDialog.SAVE);
     fd.setFile("");
     fd.show();

     String filename=fd.getFile();

     // To correct a bug in FileDialog

     if (filename!=null)
     {
        if (filename.endsWith(".*.*"))
         {
         filename=filename.substring(0,filename.length()-4);
         }
        if (filename!=null)
         {
            labelfilename=filename;
            SaveLabel(filename);
         }
     }
    }

    /**
        Called by selectedSaveLabel() and selectedSaveLabelAs()
    */
    private void SaveLabel(String filename)
    {
        try
        {

         PrintStream out=new PrintStream(new FileOutputStream(filename));
         out.println(Ser.getSingleLabel());
         out.close();
        }
        catch (IOException e)
        {throw new RuntimeException("Error in writing file" + filename);}

    }
    /**
        Called by selectedSaveFilter() and selectedSaveFilterAs()
    */
    private void SaveFilter(String filename)
    {
        try
        {

         PrintStream out=new PrintStream(new FileOutputStream(filename));
         out.println(Ser.getFilter());
         out.close();
        }
        catch (IOException e)
        {throw new RuntimeException("Error in writing file" + filename);}

    }


    /**
        Pop up the Label Dialog.
    */
    private void selectedShowLabel() {
      if (Ser!=null && Ser.getUType()==Service.U_LABEL)
      {
      SingleLabelDialog theSingleLabelDialog;
      theSingleLabelDialog = new SingleLabelDialog(this,Ser.getSingleLabel());
      theSingleLabelDialog.show();
      }
    }


    private void selectedOpenRatingServiceLabel() {
	 FileDialog fd=new FileDialog(this, "Open...",FileDialog.LOAD);
	 fd.setFile("*.rat");
     fd.show();

     String filename=fd.getFile();
     if (filename!=null)
        openService(filename,Service.U_LABEL);
    }


    private void selectedOpenRatingServiceFilter() {
     FileDialog fd=new FileDialog(this, "Open...",FileDialog.LOAD);
	 fd.setFile("*.rat");
     fd.show();

     String filename=fd.getFile();
     if (filename!=null)
        openService(filename,Service.U_FILTER);
    }

    public void selectedLoadFilter() {
     FileDialog fd=new FileDialog(this, "Open...",FileDialog.LOAD);
	 fd.setFile("*.filter");
     fd.show();
     String filename=fd.getFile();
     if (filename!=null)
        {
         FileInputStream fis;
         Filter Fil;

         try
         {fis=new FileInputStream(filename);}
         catch (FileNotFoundException e)
         {
          System.out.println("File not found");
          return;
         }
         catch (IOException e)
         {
            System.out.println("IO Exception");
            return;
         }

        try
         {
          Fil=new Filter(fis);
          System.out.println(Fil);
          Ser.setFilter(Fil);
         }
         catch (PICSException e)
         {
           try
          {fis.close();} catch (IOException ei) {System.out.println("Closing error");}

          System.out.println("PICS Filter Parsing Error:");
          System.out.println(e);
         }
         catch (IOException e)
           {System.out.println("IO error");}
       // Put the Interface Widgets of the New Service
//         removeAll();
//         Ser.newInterface(this,type,ListForLabels,SimpleFiltering);
//         show();
        }

    }


    private void welcomeMessage()
    {
     removeAll();
     setLayout(null);
     Canvas c=new LogoCanvas(Toolkit.getDefaultToolkit().getImage("W3C.gif"),
                             Toolkit.getDefaultToolkit().getImage("PICS.gif"));
     add(c);
     c.reshape(insets().left+20,insets().top+20,100,60);
     Panel p=new WelcomePanel();
     add(p);
     p.reshape(insets().left+40,insets().top+90,350,150);
    }


    private void selectedListForLabels() {
        ListForLabels=!ListForLabels;
    }


    public void selectedSaveFilter() {

        if (Ser!=null && Ser.getUType()==Service.U_FILTER)
           {
            if (filterfilename==null)
                selectedSaveFilterAs();
            else SaveFilter(labelfilename);
           }

    }

    public void selectedSaveFilterAs() {
	 if (Ser==null || Ser.getUType()!=Service.U_FILTER)
	    return;

     FileDialog fd=new FileDialog(this, "Save Filter As...",FileDialog.SAVE);
     fd.setFile("");
     fd.show();

     String filename=fd.getFile();

     // To correct a bug in FileDialog

     if (filename!=null)
     {
        if (filename.endsWith(".*.*"))
         {
         filename=filename.substring(0,filename.length()-4);
         }
        if (filename!=null)
         {
            filterfilename=filename;
            SaveFilter(filename);
         }
     }
    }

    public void selectedSimpleFiltering() {
        SimpleFiltering=!SimpleFiltering;
    }

    private Service Ser=null;
    private String labelfilename=null;
    private String filterfilename=null;
    private boolean ListForLabels=true;
    private boolean SimpleFiltering=false;

}


/**
 * AboutBox displays the information about the PICSjava program.
 */
class AboutBox extends Dialog {

    public AboutBox(Frame parent) {

	super(parent, "About", true);
	setResizable(false);

	//{{INIT_CONTROLS
	setLayout(null);
	addNotify();
	resize(insets().left + insets().right + 384, insets().top + insets().bottom + 246);
	label1=new Label("PICS Demo Code in Java", Label.CENTER);
	label1.setFont(new Font("Dialog",Font.BOLD,10));
	add(label1);
	label1.reshape(insets().left + 72,insets().top + 32,232,24);
	OKButton=new Button("OK");
	add(OKButton);
	OKButton.reshape(insets().left + 140,insets().top + 176,96,32);
	label2=new Label("ching@mit.edu", Label.CENTER);
	add(label2);
	label2.reshape(insets().left + 40,insets().top + 152,272,16);
	label3=new Label("Ching Law, Summer 1996", Label.CENTER);
	add(label3);
	label3.reshape(insets().left + 96,insets().top + 128,184,16);
	label4=new Label("The World Wide Web Consortium", Label.CENTER);
	add(label4);
	label4.reshape(insets().left + 56,insets().top + 16,264,14);
	//}}
    }

    public synchronized void show() {
	Rectangle bounds = getParent().bounds();
	Rectangle abounds = bounds();

	move(bounds.x + (bounds.width - abounds.width)/ 2,
	     bounds.y + (bounds.height - abounds.height)/2);

	super.show();
    }

    public synchronized void wakeUp() {
	notify();
    }

    public boolean handleEvent(Event event) {
	if (event.id == Event.ACTION_EVENT && event.target == OKButton) {
		clickedOKButton();
		return true;
	}
	else

	if (event.id == Event.WINDOW_DESTROY) {
	    hide();
	    return true;
	}
	return super.handleEvent(event);
    }

    //{{DECLARE_CONTROLS
    Label label1;
    Button OKButton;
    Label label2;
    Label label3;
    Label label4;
    //}}

    public void clickedOKButton() {
	handleEvent(new Event(this, Event.WINDOW_DESTROY, null));
    }
}

/**
 * The Dialog box to confirm if the user wants the quit the program
 */
class QuitBox extends Dialog {

    public QuitBox(Frame parent) {

	    super(parent, "Quit Application?", true);
	setResizable(false);

	//{{INIT_CONTROLS
	setLayout(null);
	addNotify();
	resize(insets().left + insets().right + 340, insets().top + insets().bottom + 76);
	yesButton=new Button("Yes");
	add(yesButton);
	yesButton.reshape(insets().left + 90,insets().top + 12,62,28);
	noButton=new Button("No");
	add(noButton);
	noButton.reshape(insets().left + 180,insets().top + 12,62,28);
	//}}
    }

    public synchronized void show() {
	Rectangle bounds = getParent().bounds();
	Rectangle abounds = bounds();

	move(bounds.x + (bounds.width - abounds.width)/ 2,
	     bounds.y + (bounds.height - abounds.height)/2);

	super.show();
    }

    public synchronized void wakeUp() {
	notify();
    }

    public boolean handleEvent(Event event) {
	if (event.id == Event.ACTION_EVENT && event.target == noButton) {
		clickedNoButton();
		return true;
	}
	else
	if (event.id == Event.ACTION_EVENT && event.target == yesButton) {
		clickedYesButton();
		return true;
	}
	else

	if (event.id == Event.WINDOW_DESTROY) {
	    hide();
	    return true;
	}
	return super.handleEvent(event);
    }

    //{{DECLARE_CONTROLS
    Button yesButton;
    Button noButton;
    //}}

    public void clickedYesButton() {
	System.exit(0);
    }
    public void clickedNoButton() {
	handleEvent(new Event(this, Event.WINDOW_DESTROY, null));
    }
}

/**
 * LogoCanvas draws the W3C logo and PICS logo
 */
class LogoCanvas extends Canvas
{
 public LogoCanvas(Image W3CImage,Image PICSImage)
 {
  super();
  this.W3CImage=W3CImage;
  this.PICSImage=PICSImage;
  setBackground(Color.lightGray);
 }

 public void paint(Graphics g)
 {
  g.drawImage(W3CImage,0,0,this);
  g.drawImage(PICSImage,W3CImage.getWidth(this),0,this);
 }

 private Image W3CImage;
 private Image PICSImage;
}
