/** cui.java 99/01
 *  Contextual User Interface
 *  development phase
 *  Samuel Watkins
 */

// CUI makes use of some concepts (the Model / View / Controller triple) from Smalltalk 80/MVC,
// however I have never used MVC and arrived at my conclusions independently; the central concept
// of CUI, the contextual browser, is not a part of MVC or any other major GUI to my knowledge.

// CUI is designed to work with Java 1.1, because Java 1.2 has some atrocious performance problems,
// particularly with Fonts, that make it unsuitable for serious application development.  CUI will
// run on Java 1.2, however its performance is considerably degraded.
 
import java.awt.*;
import java.awt.event.*;
import java.util.Locale;

//import struct;

// interfaces
 
interface Component {
	
}

interface Container extends Component, CUIBrowsable, Vector {
  
}

interface Root extends Container {
	
}

public interface DynamicContainer extends Container, DynamicVector {
	
}

public interface CUIBrowsable extends Browsable {
  // full CUI browser interface is supported, including insert / overtype mode
	// The insert mode features a carat between existing sub-components - it indicates
	//   positions suitable for inserting new information
	// The overtype mode highlights existing sub-components - it indicates components
	//   that can be opened, removed, copied, etc.  Overtype mode also may allow a range of
	//   components to be selected simultaneously - the CUIBrowser can maintain a selection
	//   of sub-components within its main component
	public CUIBrowser cuiBrowser();
}

// CUI generally uses a single CUIBrowser for the entire component hierarchy - the browser is the
// interface between the system and the user, the HCI.  The browser maintains a tree/network
// corresponding to the quasi-hierarchy of Views, which contains layout information,
// closed/open/active information and selection information (at least) - each node of the tree
// is a View object, but not all Models have (or even can have) individual Views.
// A special type of View is the ContainerView, which may contain layout information for
// sub-components in addition to the Container's own position.  Some ContainerViews require that
// the sub-components have individual Views, but some ContainerViews automatically
// arrange and render their sub-components according to other criteria.  The main reason for this
// is memory efficiency.  View objects may be shared (i.e. the 'tree' is not actually such!),
// e.g. for symbols in a text window.  The browser automatically extends the tree as necessary.
//
// In addition to Views, we also have Controllers, which provide user event
// handlers whereby the user can affect the components, layouts, etc. with the keyboard and mouse.
// As with the Views, a single Controller can act as the Controller for all of its
// sub-components if they are too small to merit their own individual Controllers.
// Such small components are, however, browsable by the normal mechanism, and may even be containers
// in their own right, so long as the Viewable/Controllable parent/s can handle the
// rendering/controlling for all of their descendants.
//
// There is not usually a 1-1 correspondence between Controllers and Views - any particular Model may
// have a View, and Controller, both or neither.  Depending on the activation state of the Model in
// question (closed, open, active), an event may behave differently (to control external layout,
// internal layout (pan/zoom) and the actual Model).
// In other words, the View knows about the Controller, but the Controller often does not know
// about the View (unless it is being used for manipulating it).  The Model typically knows about
// the View, but not the Controller.  So we have a cycle here - Model -> View -> Controller -> Model.
//
// This is a pleasant symmetry.  The Model changes its View/s when it is modified, the Views notify
// the Controller when an event is assigned to them, and the Controller notifies or modifies the Model
// according to the events it receives.  The View is actually primary here, from the CUIBrowser's
// point of view, as Views are typically manifold for each Model.  Maybe we can establish a better
// symmetry here, with multiple controllers being browsable also, and multiple models for a single
// view or controller?  Having multiple browsable controllers is definitely a good idea, e.g. different
// tools for a painting package.  Multiple Models for a single View is less obvious.  I don't know!!!
//
// Not every Model need be an actual object; characters in a String, for example, are acceptable
// Models.  The CUIBrowser will simply remember an integer index into the 'Container' that
// might be something like a String or StringBuffer, for example.
// It is even possible to use a large String as a line of text containing words containing characters.
//
// CUI supports virtual-Models, virtual-Views and virtual-Controllers, which are effectively the same
// as Models, Views and Controllers but are not implemented as Objects.  The Object parent/ancestor of
// a virtual M, V or C is responsible for its child/descendent virtual Ms, Vs or Cs.  These virtual
// children are designated by special keys in addition to their responsible Object's handle.
// The responsible Object serves and keeps track of these keys; the actual meaning of each key is
// indirected through a lookup/vector table to enable the meanings to be modified (e.g. if an extra
// character is inserted into a String, the meanings of keys to characters after that point must be
// updated.)  Keys should be disposed of when no longer in use, to economise memory usage.

public interface CUIBrowser extends Browser {
	public static final int MODE_OVERTYPE = 0;
	public static final int MODE_INSERT = 1;
	public static final int STATE_CLOSED = 0;
	public static final int STATE_OPEN = 1;
	public static final int STATE_ACTIVE = 2;
	public void setMode(int mode); // overtype/insert mode applies to the entire CUIBrowsable
  public int mode();
	public void setSelect(boolean selected); // selection applies to sub-components individually
	public boolean select();
	public void setState(int state); // closed/open/active state applies to sub-components individually
	public int state();
//	public void setLayout(Layout l);
//	public Layout layout();
}

public interface Model {
	
}

public class DefaultCUIBrowser implements CUIBrowser {
	private int subIndex = -1; // used to implement non-object leaves, -1 means at an object leaf
	private ComponentImage at; // if the current component is a non-object leaf, this indicates its parent
  private ComponentController
}

/*
public interface Controllable extends Component {
	public Port_Output_EventControl getControlPort();
}

public interface Renderable extends Component {
	public void setGraphicsPort(Port_Input_EventGraphics);
}

public interface Touchable extends Component {
	public Port_Output_EventTouch getTouchPort();
}

public interface Playable extends Component {
	public Port_Output_EventControl getControlPort();
}
*/

// classes

public class Colors extends Color {
	public static final Color brown = new Color(160,128,96);
	public static final Color darkBrown = new Color(96,64,32);
	
	public Colors() {super(0,0,0);}
}

public class Container_1 implements Container {
	awtRH.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
	private RenderingHints awtRH = new RenderingHints(null);
	
	private Font font = new Font("Serif", Font.PLAIN, 14);
		
  public void render(Graphics2D g) {
		g.addRenderingHints(awtRH);
		g.setColor(awtColor_Back);
		g.fillOval(32,32,64,64);
		g.setColor(awtColor_Top);
		g.fillOval(128,32,64,64);
		g.setColor(awtColor_TopFocus);
		g.fillOval(128,128,64,64);
		g.setColor(Colors.white);
		g.setFont(font);
		g.drawString("The Quick Brown Fox Jumped Over The Lazy Dog",256,256);
		g.drawString("THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG",256,256+32);
		g.drawString("12345678901234567890123456789012345678901234",256,256+64);
		g.drawString("!@#$%^&*()-=_+|[]{};:,.<>/?`~",256,256+96);
		Locale l = Locale.getDefault();
    g.drawString(l.getDisplayLanguage (l),256,256+160);
		g.drawLine(256,256,512,300);
  }
}

public class DefaultRoot extends DefaultContainer, implements Root {
  private static Toolkit awt = Toolkit.getDefaultToolkit();

	private Color awtColor_Top = Colors.gray;
	private Color awtColor_Back = Colors.darkGray;
	private Color awtColor_TopFocus = Colors.brown;
	private Color awtColor_BackFocus = Colors.darkBrown;

	private Frame awtFrame = new Frame();
	private Root_1_Window awtWindow = new Root_1_Window(awtFrame);

	public Root_1() {
	}

	class Root_1_Window extends Window implements MouseListener, MouseMotionListener, KeyListener {
		public Root_1_Window(Frame owner) {
			super(owner);

			setBackground(awtColor_BackFocus);
			setSize(awt.getScreenSize());
			setLocation(0,0);
			setVisible(true);
			
			addMouseListener(this);
			addMouseMotionListener(this);
			addKeyListener(this);
		}
	
		/*
		public void update(Graphics g) {
		}
		*/
		
		public void paint(Graphics _g) {
			Graphics2D g = (Graphics2D)_g;
			Root_1.this.render(g);
		}
	
	  public void mouseClicked(MouseEvent e) {
	  }
	
	  public void mouseEntered(MouseEvent e) {
	  }
	
	  public void mouseExited(MouseEvent e) {
	  }
	
	  public void mousePressed(MouseEvent e) {
	  }
	
	  public void mouseReleased(MouseEvent e) {
	  }
	
	  public void mouseDragged(MouseEvent e) {
	  }
	
	  public void mouseMoved(MouseEvent e) {
	  }
		
	  public void keyPressed(KeyEvent e) {
	  }
	
	  public void keyReleased(KeyEvent e) {
	  }
	
	  public void keyTyped(KeyEvent e) {
	  }
	}
		
	public int getCount() {
		return 0;
	}
}

// test

class TestCUI {
	public static void main(String [] args) {
		Root root = new Root_1();
  }
}