/*
The code is available only to persons
currently affiliated with any of the following,
      o Universities and schools
      o Non-commercial research organizations
      o Registered not-for-profit organizations
      o Registered charities
For these people, the license is of the form of
the GNU Public License version 2.  The restrictions
must remain attached to this and any subsequently derived code.
All other people have no implicit right to use, read, or copy
this software unless granted by Mr. Deck
THIS SOFTWARE IS PROVIDED "AS IS" AND MR. DECK
MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, HE
MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANT-
ABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE
OF THE LICENSED SOFTWARE AND DOCUMENTATION WILL NOT
INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR
*/

import java.awt.*; 
import java.util.Random;
import java.util.Hashtable;
import java.applet.Applet;
import java.io.IOException;

public class icontext extends Applet implements Runnable{
Thread          t = null;
drawArea       da = null;
label      usrLab = null;
List          lst = null;
Character curChar = null;
connection    con = null;
Hashtable    ctab = null; 
textArea       ta = null;
chiclet      chic = null;
control      cntl = null;
saveDlg     saveD = null;
openDlg     openD = null;
int       curItem = 0;
int      numUsers = 0;
boolean     IEBUG = false;
boolean      MSIE = false;

   public void init(){
	curChar = new Character(' ');
	setBackground(Color.white);
	setLayout(null);
	String fonts[] = getToolkit().getFontList();
        for(int i=0;i<fonts.length;i++){
             if(fonts[i].equals("Monospaced")){
		env.font = new Font(fonts[i],Font.PLAIN,12);
		break;
	     }
        }
	setFont(env.font);
	add(ta = new textArea(this));
	ta.reshape(252,0,500,500);

	usrLab = new label("/*  Connecting to server...   */");
	usrLab.setFont(env.font);
	usrLab.move(0,250);
	usrLab.resize(130,20);
	usrLab.reshape(1,251,249,27);
        add(usrLab);

	rose ro = new rose(this);
	ro.move(147,290);
	ro.resize(90,45);
	ro.reshape(147,290,90,45);
	add(ro);

	langPicker lp = new langPicker(this);
	lp.setFont(env.font);
	//lp.move(143,480);
	lp.resize(93,15);
	lp.reshape(143,480,96,15);
	add(lp);

	asciiBut lo = new asciiBut("HELPINFO",this);
	lo.move(148,348);
	lo.resize(100,60);
	lo.reshape(148,348,60,40);
	add(lo);

	asciiBut saveB;
	saveB = new asciiBut("SAVEFILE",this);
	saveB.move(148,428);
	saveB.resize(70,30);
	saveB.reshape(148,428,58,40);
	add(saveB);

	asciiBut openB;
	openB = new asciiBut("OPENFILE",this);
	openB.move(148,388);
	openB.resize(70,30);
	openB.reshape(148,388,58,40);
	add(openB);

	add(chic = new chiclet(Color.black,this));
	chic.move(9,282);
	chic.resize(51,25);
	chic.reshape(9,282,120,20);

	lst = new List();
	lst.setFont(env.font);
	lst.move(9,306);
	lst.resize(120,185);
	lst.reshape(9,306,120,185);

	Random rnd = new Random(21);
	ctab = new Hashtable();
	int r, g, b;
        lst.addItem("   #FFFFFF");
        lst.addItem("!  #000000");
	Character ch=null;
	for(int i=35;i<=126;i++){
	   if(i!='<'){
	    Color c = new Color(r=Math.abs(rnd.nextInt()%255),
                                g=Math.abs(rnd.nextInt()%255),
                                b=Math.abs(rnd.nextInt()%255));
	       ctab.put(ch=new Character((char)i), c);
               lst.addItem(ch.toString()+"  #"+getHex(r,g,b));
	   }
	}
	ctab.put(curChar,Color.white);
	ctab.put(curChar=new Character((char)'!'), Color.black);
	add(lst);
	lst.select(curItem);

	add(da = new drawArea(this));
	da.move(0,0);
	da.resize(250,250);
	da.reshape(0,0,250,250);

        String str = getParameter("xpm");
	if(str!=null)
		new loadXPM(this,str);
        str = getParameter("BROWSER");
	if(str!=null){
	   if(str.equals("MSIE"))
		 MSIE = true;
	}
	repaint();
   }

//what if over 255?
   public String getHex(int r_in,int g_in,int b_in){
	int r1 = r_in>>4;
	int r2 = r_in%16;
	int g1 = g_in>>4;
	int g2 = g_in%16;
	int b1 = b_in>>4;
	int b2 = b_in%16;
	return (String)(dec2hex(r1)+dec2hex(r2)+dec2hex(g1)+dec2hex(g2)+dec2hex(b1)+dec2hex(b2));	
   }

   public String dec2hex(int i){
	if(i<10) 
	  return Integer.toString(i);
	else{     
	  byte b[] = {(byte)(i+55)};
          return new String(b,0);
	}
   }

   public boolean handleEvent(Event e){
     if(e.target instanceof List){
	if(e.id==Event.LIST_SELECT){
	   if(!IEBUG){
		String s = 
		((List)e.target).getItem(curItem=((Integer)(e.arg)).intValue());
		curChar  = new Character(s.charAt(0));
		chic.setColor((Color)ctab.get(curChar));	
		chic.setColor(chic.getColor());
		if(chic.cSel!=null && chic.cSel.isVisible()){
			if(chic.disp) {
                           chic.cSelect();
			}
			chic.disp = true;
		}
		chic.repaint();
	   }
	   else{ 
		if(MSIE) IEBUG=!IEBUG;
	   }
	   usrLab.setText(env.kcol);
	}
	else if(e.id==Event.ACTION_EVENT){
    		if(e.target instanceof List){
			chic.cSelect();
		}
		else if(e.id== Event.KEY_ACTION)
			System.out.println("key action");
		else
			System.out.println("some action");
	}
    }
    else if(e.id==Event.MOUSE_DOWN){
	if(e.target instanceof asciiBut){
		String lbl = ((asciiBut)e.target).getLabel();
		if( lbl.equals("HELPINFO")){
			if(cntl!=null){
				cntl.dispose();
			}
			cntl=null;
			cntl = new control(this);
			cntl.show();
		}
		else if( lbl.equals("OPENFILE")){
		      if(openD!=null){
		          openD.dispose();
                        }
                        openD = null;
                        openD = new openDlg(this);
			openD.show();
		}
		else{
		        if(saveD!=null){
                          saveD.stop();
		          saveD.dispose();
                        }
                        saveD = null;
                        saveD = new saveDlg(this);
			saveD.show();
		}
	}
    }
    else if(e.target instanceof asciiBut){
 	if(e.id == Event.MOUSE_ENTER){
	  if(((asciiBut)e.target).getLabel().equals("HELPINFO")){
		usrLab.setText(env.nav);
	  }
	  else if(((asciiBut)e.target).getLabel().equals("SAVEFILE")){
		usrLab.setText(env.save);
	  }
	  else  usrLab.setText(env.open);
	
	}

    }
    else if(e.id == Event.KEY_ACTION){
		return false;
    }
    return true;
  }


  public void setUsers(){
      usrLab.setText((String)("/*  "+numUsers+(numUsers>1?" "+env.users:" "+env.user)+"  */"));
  }


  public void paint(Graphics g){ 
	g.drawLine(250,0,250,500);
	g.drawLine(0,250,250,250);
  }

  public void start(){
	t = new Thread(this);
	t.setPriority(Thread.MIN_PRIORITY);
	t.start();
  }

  public void stop(){
	closeConnection(env.disconnected);
        if(chic.cSel != null) chic.cSel.hide();
	if(cntl !=null) cntl.hide();
	if(saveD !=null) saveD.hide();
	if(t!=null) t.stop();
	t=null;
  }

  private void closeConnection(String msg){
      if(con != null) con.close();
      con = null;
      usrLab.setText("/*  "+msg+"  */");
  }

  public void destroy(){
        da.flush();
        if(con != null)      con.error = true;
        if(chic.cSel != null) chic.cSel.dispose();
	if(cntl !=null) cntl.dispose();
	if(saveD !=null) saveD.dispose();
  }

  public void run(){
     byte[] buf;
     char b=0;
     int x, y;
     Character ch=null;
     Color hold = null;
	con = new connection(env.host,env.port,usrLab); 
        String mode = getParameter("mode");
	if(mode!=null && mode.equals("private")){
		t=null;
		con.close();
		con.error = true;
	}
	if(con!=null) usrLab.setText(env.connecting);
	while(t!=null){
 	    try{
		if(con!=null && !con.error) 
			buf = con.receive();
		else buf=null;
		if(buf!=null){
		     if(buf[0] != 0){
			switch(buf[0]){
				case 100:
				  numUsers=buf[1];
				  setUsers();
				 break;
			}
		     }
		     else{
		      b = (char)((buf[4]<128&&buf[4]>32?buf[4]:' ')&0x00ff);
		      ch = new Character(b);
		      x = 10*buf[2];
		      y = 10*buf[3];
	              ta.setElement(x,y,(int)buf[2],(int)buf[3],ch);
                      if(da.G!=null){
                         hold = da.G.getColor();
			 da.G.setColor((Color)(ctab.get(ch)));
                         da.G.fillRect(x>>1,y>>1,5,5);
			 da.G.setColor(hold);
                      }		      
		    }
		}else break;
	}catch(IOException io){
		io.printStackTrace();
	}catch(Exception e){
		e.printStackTrace();
	}
     }
     usrLab.setText("/*  "+env.disconnected+"  */");
  }
}
