import java.io.*;
import java.net.*;
import java.awt.*;
import java.util.*;
import java.util.zip.*;

//public class asciiJam extends Frame {
public class asciiJam extends java.applet.Applet implements Runnable{
Image       img = null;
textArea     ta = null;
Color curCol = Color.white;
int   curColorIndex = 215;
public int tool = 4;
label usrLab = null;
label totalLab = null;
TextField tf;
floodFill ff;
rectangle rect;
oval oval;
eraser ersr;
mapFrame mapF = null;
tabbedpane tpane;
Checkbox cb = null;
line line;
palette pal;
keyboard kbd;
toolbar tb;
saver svr;
Graphics g;
String host = "";
int[] tmptxt = new int[(env.width>>3)*(env.height>>3)];
figLoader fl = null;
Thread t = null;
Socket sock = null;
boolean connected = false;
//ajData m = null;
D m = null;
BufferedOutputStream  output = null;
//GZIPOutputStream  output = null;
Vector sendBuffer;
sender send;
boolean msBadGraphics = false;
char fillChar = 'X';

   public static void main(String arg[]){
		asciiJam r = new asciiJam();
		r.show();
		r.init(r);
   }
   public void init(){

   	  init(this);
      sendBuffer = new Vector();
	  System.out.println(env.VERSION);
   }
   public void init(asciiJam aj){
        Dimension dim = size();
	    if(img==null){
           //img = ((Component)this).createImage(1024,1024); //env.width*3,env.height*3);
           img = aj.createImage(1024,1024); //env.width*3,env.height*3);
        }
        Graphics g = img.getGraphics();
        g.setColor(Color.black);
        g.fillRect(0,0,env.width*3,env.height*3);
        g.setFont(env.dialogFont);

   		setLayout(null);
   		setBackground(Color.gray);
        setFont(env.dialogFont);
   		tpane = new tabbedpane(this);
		tpane.reshape(0,0,132,1024);
		Panel basic = tpane.addTab("main");
		basic.setLayout(null);
		tb = new toolbar(aj);
        tb.reshape(12,40,31,211);
        pal = new palette(aj);
        //pal.reshape(59,40,60,350);
        pal.reshape(59,40,60,242);

		usrLab = new label("");
        usrLab.setFont(env.dialogFont);
		//usrLab.setFont(new Font("Helvetica",Font.PLAIN,11));
        usrLab.reshape(4,8,122,22);

		totalLab = new label("");
        totalLab.setFont(env.dialogFont);
		///totalLab.setFont(new Font("Helvetica",Font.PLAIN,11));
        totalLab.reshape(4,258,48,22);

		aj.ff= new floodFill(aj);
        aj.ff.setFont(env.dialogFont);
        basic.add(aj.ff);
        ff.reshape(4,300,123,275);
        ff.hide();

        aj.rect= new rectangle(aj);
        aj.rect.setFont(env.dialogFont);
        basic.add(aj.rect);
        aj.rect.reshape(4,294,123,290);
        aj.rect.hide();

        aj.oval= new oval(aj);
        aj.oval.setFont(env.dialogFont);
        basic.add(aj.oval);
        aj.oval.reshape(4,294,123,290);
        aj.oval.hide();

        aj.line= new line(aj);
        aj.line.setFont(env.dialogFont);
        basic.add(aj.line);
        //aj.line.reshape(4,300,123,200);
        aj.line.reshape(4,300,123,275);
        aj.line.show();
        aj.line.hide();

        kbd= new keyboard(aj);
        aj.kbd.setFont(env.dialogFont);
        basic.add(kbd);
        kbd.reshape(4,300,123,200);
        kbd.hide();

        svr= new saver(aj);
        aj.svr.setFont(env.dialogFont);
        basic.add(svr);
        svr.reshape(4,300,123,200);
        svr.hide();

        aj.ersr= new eraser(aj);
        aj.ersr.setFont(env.dialogFont);
        basic.add(aj.ersr);
        aj.ersr.reshape(4,300,123,222);
        aj.ersr.hide();

        basic.add(pal);
        basic.add(tb);
        basic.add(usrLab);
        basic.add(totalLab);

		mapF = new mapFrame(aj);
		mapF.reshape(2,2,130,130);
		Choice c = new Choice();
        c.add("100%");
        c.add("200%");
        c.add("400%");
        c.move(4,132);

		cb = new Checkbox("Private drawing",false);
		cb.setFont(new Font("Helvetica",Font.PLAIN,10));
		cb.reshape(4,180,66,30);

		Panel extra = tpane.addTab("view");
        extra.add(mapF);
        extra.add(c);
		extra.add(cb);

		help h = new help(aj);
		h.reshape(4,30,120,200);

		Panel help = tpane.addTab("help");
		help.add(h);
		//tpane.showTab("view");
		tpane.showTab("main");
		reshape(0,0,132,1024);
		add(tpane);

        aj.ta=new textArea(aj);
		ta.reshape(133,0,1024,1024);
		add(ta);

   }

   public boolean handleEvent(Event e){
        //if(e.id==201) System.exit(0);
		if(e.target instanceof Panel){
			if(e.id==Event.MOUSE_ENTER) env.setCursor(env.DEFAULT_CURSOR,this);
			//else if(e.id == Event.MOUSE_EXIT)	 env.setCursor(tool,this);
        }
		else if(e.target instanceof Choice){
            if(e.arg!=null){
                if(((String)e.arg).indexOf("100%")>=0) ta.zoom(1);
                else if(((String)e.arg).indexOf("200%")>=0) ta.zoom(2);
                else if(((String)e.arg).indexOf("400%")>=0) ta.zoom(4);
				else return true;
				mapF.boundPt(mapF.x,mapF.y);	
                ta.fillGrid();
				if(tpane.hot==1) mapF.repaint();
				ta.requestFocus();
                return true;
            }
        }
		return false;
  }

  public void start(){
	t = new Thread(this);
    t.start();
  }
  public void stop(){
	try{
		if(sock!=null) sock.close();
    }catch(Exception e){
		e.printStackTrace();
	}
    if(t!=null) t.stop();
    t = null;
  }
  public void run(){
    try {
        sock = new Socket(env.host, env.ajamServerPort);
		connected = true;
    } catch (Exception e3) { 
		e3.printStackTrace();
    }
	g = img.getGraphics();
	g.setFont(env.font[ta.zoom]);
		///tpane.showTab("main");
    try{ msBadGraphics = getGraphics().getClass().toString().equals("class com.ms.awt.GraphicsX");
    } catch(Exception e){ System.out.println("bad g"); }
	if(!connected){
		totalLab.setText("Blocked");
		 return;
    }
	usrLab.setText("Connected");
	if(send==null||((Thread)send).isAlive()==false){
      send = new sender(this);
      send.start();
    }



    try {
        //output = new BufferedOutputStream(new GZIPOutputStream(sock.getOutputStream()));
        //output = new GZIPOutputStream(new BufferedOutputStream(sock.getOutputStream()));
        //BufferedInputStream bis = new BufferedInputStream(new GZIPInputStream(sock.getInputStream()));
        //GZIPInputStream gis = new GZIPInputStream(new BufferedInputStream(sock.getInputStream()));
        //output = new GZIPOutputStream(sock.getOutputStream());
        output = new BufferedOutputStream(sock.getOutputStream());
        //GZIPInputStream gis = new GZIPInputStream(sock.getInputStream());
        BufferedInputStream gis = new BufferedInputStream(sock.getInputStream());
		System.out.println("output="+output+" bis="+gis);
        ObjectInputStream input  = null; 
        //byte msg[]={(byte)'A',(byte)'r',(byte)'r',(byte)'r',(byte)'i',(byte)'v',(byte)'e'};
        String msg="Arrive";
        send(new D(env.ARRIVAL,0,msg,0));
		m = new D(0,0,"",0);
        while(connected){
           input  = new ObjectInputStream(gis);
		   //m = (ajData) input.readObject();
		   //m = (D) input.readObject();
		   ((D)m).readExternal(input);
		   if(msBadGraphics){
		     try{ t.sleep(5); }catch(InterruptedException ie){}
           }
		   if(m.typ==env.SETCHAR)
			  //ta.setcharRemote(m.a,m.index,m.color,pal.palette[m.color],g);
			  ta.setcharRemote(new String(m.a),m.idx,m.col,pal.palette[m.col],g);
		   else if(m.typ==env.DEPARTURE)
			 totalLab.setText(""+m.idx+" user"+(m.idx<2?"":"s"));
		   else if(m.typ==env.ARRIVAL) 
			 totalLab.setText(""+m.idx+" user"+(m.idx<2?"":"s"));
		   //ta.repaint();
        }
    } catch (IOException e2) { 
		    e2.printStackTrace();
    } catch (Exception e3) { 
		    e3.printStackTrace();
    }
	try{
		if(output!=null) output.close();
		if(sock!=null) sock.close();
		sock = null;
    }catch(Exception e){
		e.printStackTrace();
	}
	usrLab.setText("Disconnected");
	totalLab.setText("Private");
    cb.setState(true);	
  }

  public void send(Object o){
		//System.out.println("sending");
        try{
          ByteArrayOutputStream bos = new ByteArrayOutputStream();
          ObjectOutputStream    out = new ObjectOutputStream(bos);
          //out.writeObject((ajData)o);
		  ((D)o).writeExternal(out);
          //out.writeObject((D)o);
          out.close();
		  byte arr[] = bos.toByteArray();
		 //System.out.println("length="+arr.length);
		 //for(int i=0;i<arr.length;i++)  System.out.println((char)arr[i]);
          output.write(bos.toByteArray());
          output.flush();
        } catch (IOException e2) { 
		    e2.printStackTrace();
        } catch (Exception e3) { 
		    e3.printStackTrace();
        }
  }
}
