package extensions.awt;
import java.awt.*;
import java.io.*;
import java.util.*;
import extensions.io.*;
import extensions.util.*;

/* Destroy all frames. */
class JeditExitAllAdapter extends Action
{ public void run() { Jedit.exitAll(); }}

class JeditSpawnWindowHandler extends Action
{
  boolean newFile, readOnly, promptUser;
  JeditSpawnWindowHandler
    (boolean newFile, boolean readOnly, boolean promptUser)
  {
    this.newFile = newFile;
    this.readOnly = readOnly;
    this.promptUser = promptUser;
  }
  public void run()
  {
    Jedit je = (Jedit) forward;
    je = (Jedit) je.spawn
      ((newFile?null:je.getFile()),readOnly,promptUser);
    if (je.userCanceled())  {
      je.destroy();
      ((Jedit) forward).toFront();
    }
    else
      je.show();
  }
}

class JeditNewWindowHandler extends JeditSpawnWindowHandler
{ JeditNewWindowHandler() { super(true,false,false); } }

class JeditOpenWindowHandler extends JeditSpawnWindowHandler
{ JeditOpenWindowHandler() { super(false,false,true); } }

class JeditBrowseWindowHandler extends JeditSpawnWindowHandler
{ JeditBrowseWindowHandler() { super(false,true,true); } }

class JeditCloneWindowHandler implements ActionProtocol
{
  public void action(Component forward, Event evt, Object what)
    { ((FrameExtended)(((Jedit)forward).clone())).show(); }
}

public class Jedit extends EditFrame
{

  static void exitAll()
  {
    FrameExtended fe;
    EditFrame ef;
    Enumeration frames = instances.instances();
    while (frames.hasMoreElements())  {
      fe = (FrameExtended) frames.nextElement();
      if (fe instanceof EditFrame)  {
        ef = (EditFrame) fe;
        if (!ef.dirty())  {
          ef.hide();
          if (ef.exitOnDestroy)
            System.exit(ef.exitStatus());
          if (ef.disposeOnDestroy)
            ef.dispose();
        }
      }
    }
    destroyFrames();
    if (FrameExtended.exitOnDestroyAll)
      System.exit(0);
  }

  private void init()
  {
    Menu m = getMenuBar().getMenu(0);
    m.addSeparator();
    m.add(new MenuItemAction("Exit All",new JeditExitAllAdapter()));
    m = new Menu("Windows");
    m.add(new MenuItemAction("New",new JeditNewWindowHandler()));
    m.add(new MenuItemAction("Browse ...",new JeditBrowseWindowHandler()));
    m.add(new MenuItemAction("Open ...",new JeditOpenWindowHandler()));
    m.add(new MenuItemAction("Clone",new JeditCloneWindowHandler()));
    m.addSeparator(); 
    m.add(new MenuItemAction("List ...",pickFrameAdapter()));
    m.add(new MenuItemAction("Cascade",cascadeFramesAdapter()));
    getMenuBar().add(m);
  }

  public Jedit()
    { init(); }

  public Jedit(Jedit je)
  {
    super((EditFrame)je);
    init();
  }

  public Jedit(File f, boolean readOnly, boolean promptUser)
  {
    super(f,readOnly,promptUser);
    init();
  }

  /** Clone this Jedit along with its contents.
    * The cloned Jedit is in browse (read only) mode
    */
  public Object clone()
    { return new Jedit(this); }

  /** Spawn a new Jedit. */
  public Object spawn(File f, boolean readOnly, boolean promptUser)
  {
    if (f == null)
      return new Jedit();
    return new Jedit(f,readOnly,promptUser);
  }

  /** Save to file, interactively.
    * @param prompt prompt user if any dirty
    * @return false only if user cancels
    */
  public boolean saveAll(boolean prompt)
  {
    Enumeration frames = instances.instances();
    FrameExtended fe;
    boolean dirty = false;
    while (frames.hasMoreElements())  {
      fe = (FrameExtended) frames.nextElement();
      if (fe instanceof Jedit)
        if (((Jedit)fe).dirty())
          dirty = true;
    }
    if (!dirty)
      return true;
    frames = instances.instances();
    while (frames.hasMoreElements())  {
      fe = (FrameExtended) frames.nextElement();
      if (fe instanceof EditFrame)
        if (!((EditFrame)fe).save(this,true))
          return false;
    }
    return true;
  }

  public static void main(String[] args)
  {
    exitOnDestroyAll = true;
    if (args.length == 0)
      (new Jedit()).show();
    else
      for (int i = 0; i < args.length; i++)
        (new Jedit(new File(args[i]),false,false)).show();
  }
}