import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.awt.*;

public class tablet extends Thread {
Wacom wacom;
openStudio ops; 
Event evt; 

	tablet(openStudio ops){
		this.ops = ops;  
		start();
	}	

	public void  run(){
	int xpos=-1, 
		ypos=-1, 
		oxpos=-1, 
		oypos=-1,
		pval=-1, 
		opval=-1, 
		s1=0, 
		os1=0, 
		xsign=-1, 
		ysign=-1, 
		b=0,
		bval=0,
		x1=0,
        y1=0;
	int phase = 1;
	long time = System.currentTimeMillis();
	boolean button=false;
	boolean down=false;
	evt = new Event(this,0, "foo");
    	try{
	    	wacom = new Wacom("/dev/cua0");	

		   	while(true){ 
				b= (int) (wacom.fis).read(); 
				if( (b&0x80)>0 ) break;
		   	}
		   	//while (t!=null){
		   	while (true){
			  switch(phase) {
            		case 1:
			//button = ((b>>3)&1)>0;
			//down=((b>>3)==29?true:false); 
                    	if((b&0x04)>0) xsign = -1;
                    	else xsign = 1;
                    	xpos = b&0x03;
						break;
			   		case 2:
						xpos = (xpos<<7) + (b&0x7f);
						break;
			  		case 3:
                		xpos = xsign * ((xpos<<7) + (b&0x7f));
                		break;      
			  		case 4:
                    	if((b&(0x04))>0) ysign = -1;
                    	else ysign = 1;
                    	ypos = b&0x03;
						//bval = (b&(0x0C))>>2;
						if((b&(0x10))>0) bval = 0;
						else bval = 1;	
                		break;      
			  		case 5: 
						ypos = (ypos<<7) + (b&0x7f);
                		break;          
			  		case 6:
                		ypos = (ypos<<7) + (b&0x7f);
                		break;              
			  		case 7:
               		 pval = b&0x3f;
                   	 if((b&0x40)>0) pval = pval | 0xffffffc0;
				 if(pval>-59){
					if(down) {
					   ops.dp.curItem.press = (byte)ops.pr[pval+59];
					   evt.id = 0;
			            	   ops.dp.mouseDrag(evt,(xpos>>4),(ypos>>4));
					}
					else{
					   ops.dp.repaint(oxpos,oypos,3,3);
					   ops.dp.curItem.press = (byte)0;
			                   ops.dp.mouseDown(evt,(xpos>>4),(ypos>>4));
						down=true;
					}
				} else {
						ops.dp.repaint(oxpos,oypos,3,3);
					        x1= xpos>>4;
						y1=ypos>>4;
						Graphics g = ops.dp.getGraphics();
						g.setColor(Color.red);
						g.fillRect(x1,y1,2,2);
						g.setColor(Color.green);
						g.drawRect(x1,y1,2,2);
						g.dispose();
						if(!down){
							ops.dp.mouseMove(evt,(xpos>>4),(ypos>>4));
						}
							/*ops.handleEvent(
							new Event((Object)this,System.currentTimeMillis(), Event.MOUSE_MOVE,x1,y1,-1,0));
	*/
						else { 
							ops.dp.mouseUp(evt,(xpos>>4),(ypos>>4));
							/*ops.handleEvent(
							new Event((Object)this,System.currentTimeMillis(), Event.MOUSE_UP,x1,y1,-1,0));*/
							down=false;
						}
					  oxpos = x1; 
					  oypos = y1; 
					}
		}
		phase++;
		b= (int) (wacom.fis).read(); 
	 	if((b&0x80)>0){
			if(phase !=8){ 
			     //new printByte((byte)b);	
				 System.out.println("phase "+ phase+" has parity bit");
	     			while(true){ 
				      b= (int) (wacom.fis).read(); 
					if( (b&0x80)==0x80 ) break;
					else System.out.println("Out of phase"+b);
				}
			}
			if(bval==0) {
			 if(System.currentTimeMillis() - time > 200){ 
					if(ops.cntl.cpick.rgb[0]==100)
                    	 ops.cntl.cpick.rgb[0]=ops.cntl.cpick.rgb[1]=ops.cntl.cpick.rgb[2]=0;
					else ops.cntl.cpick.rgb[0]=ops.cntl.cpick.rgb[1]=ops.cntl.cpick.rgb[2]=100;
					ops.cntl.cpick.repaint();
					bval=-1;
			 }
			 time = System.currentTimeMillis();
			}
			phase = 1;
                }
	   }
         } catch (Exception e){ e.printStackTrace(); } 
	   System.out.println("out");
	}
}



class Wacom
{
     FileInputStream fis;
     FileOutputStream fos;
     DataInputStream dis;

     public Wacom(String fname) throws IOException {
         fos = new FileOutputStream(fname);
         fis = new FileInputStream(fname);
         tablet_init(fname);
     }

      public void tablet_init(String fname) throws IOException {
        byte init[]={
          'D','E','0','\r',
          'F','M','0','\r',
          'P','H','1','\r',
          'I','T','0','3','\r',
          'S','R','\r',
          //'A','L','2','\r',
          'M','U','0','\r',
          'S','T','\r',
          'I','N','2','\r',
          'N','R','2','0','0','0','\r' };
           fos.write(init);
     }

     public void close() throws IOException {
        fos.close();
        fis.close();
     }

/*     public int getMax() throws IOException {
*       byte coord[]={'~','C','\r'};
*       byte resp[];
*       int len=14, available;
*       fos.write(coord);
*       resp = new byte[len];
*       //resp = new byte[fis.available()];
*        fis.read(resp);
*       System.out.println(new String(resp,0));
*       return 1;
*     }
*
*     public int getModel() throws IOException {
*       byte query[]={'~','#','\r'};
*       byte resp[];
*       int len=17, available;
*       fos.write(query);
*       resp = new byte[len];
*        fis.read(resp);
*       System.out.println(new String(resp,0));
*       return 1;
*     }                                                    
*
*     public int getSettings() throws IOException {
*       byte query[]={'~','R','\r'};
*       byte resp[];
*       int len=25, available;
*       fos.write(query);
*       resp = new byte[len];
*        fis.read(resp);
*       System.out.println(new String(resp,0));
*       return 1;
*     }
*/
}                   
