/*  1000 Points of Light, Phase 2
 
 The applet is 250 pixels wide, and the square image
 extends down to the y=250 row. Below y=250 is a message
 and dialog panel area that is 100 pixels high.  
 In terms of data, the image is 50x50, or in other
 words, it has 2500 pixels.  But we will be drawing 5x5
 blocks, thereby creating an image that is 5 times 50x50,
 or 250x250.  
*/

import java.awt.*;
import java.util.*;

public class draw extends java.applet.Applet{

Image     img; 
Graphics  img_g;
Graphics  app_g;
Random    rand; 
Label l;
int       array[][];
int       cnt = 1000;
int       old_col;
int       old_row;
int       encoded[]; 
int       submitted = 0;
int       SUBMIT_wid;
final int WHITE  = 1;
final int BLACK  = 0;
final int WIDTH  = 250;
final int HEIGHT = 250;
final int two[]={ 1,2,4,8,16,32,64,128,256,512,1024,2048,
                            4096,8192,16384,32768 };
                        // the powers of two up to 16

	public void init(){
               array   = new int[50][50];
	       app_g   = getGraphics(); 
	       img     = createImage(50,50);
               img_g   = img.getGraphics();
	       rand    = new Random();
               encoded = new int[157];
		FontMetrics fm = app_g.getFontMetrics();
		SUBMIT_wid = fm.stringWidth("SUBMIT");
		String s = getParameter("SUB");
	       if(s==null) submitted = 0;
	       else submitted = Integer.parseInt(s);
	       paramToArray(getParameter("DATA"));	
	       l = new Label();		
	       setLayout(new BorderLayout());
		add("South", l);
	}


	public boolean handleEvent(Event e){
	   
         if( e.y < HEIGHT && 
	     e.y >= 0     && 
             e.x >= 0     && 
             e.x < WIDTH )
	 {  
	
	    int row = e.y/5;        // convert from range 0-250 to 0-50 
	    int col = e.x/5;        // convert from range 0-250 to 0-50
		
	    switch( e.id ){
		case Event.MOUSE_UP:
	     		l.setText(cnt+" Points of Light");
			// count the white pixels and print message
	     		cnt = 0;
			for(int r=0;r<50;r++){
			  for(int c=0;c<50;c++){
				 if(array[r][c]==WHITE) cnt++; 
			  }
			}
			updateMsg();
	    		break;
	 	case Event.MOUSE_DOWN:
		case Event.MOUSE_DRAG:
			if(e.id==Event.MOUSE_DOWN){
			  if(array[col][row]==WHITE) app_g.setColor(Color.black);
			  else  	             app_g.setColor(Color.white);
			} 
	                else{ if (col==old_col && row==old_row) return true; } // return immediately
		        // both events share the rest of the actions
		      if(app_g.getColor()==Color.black) array[col][row]=BLACK;  
		      else array[col][row]=WHITE;
			app_g.fillRect(col*5,row*5,5,5); 
				// convert back to 0-250 range
			break;
		case 1005:
			repaint();
			break;
	    }
	    old_row = row;
	    old_col = col;
	 }
	 else  // not within bounds of picture
	 {
	     if(e.id==Event.MOUSE_DOWN && cnt==1000 && submitted==0) submitImage();   
	 }
	 return true;
        } // end of handleEvent



	    // The default update method will
	    // clear the whole applet each time -- but
	    // that ends up being distracting, so we 
	    // re-define it without the clear
	public void update(Graphics g){ 
		paint(g);
	}

	public void paint(Graphics g){
	     l.setText(cnt+" Points of Light");
	     updateMsg();
	     // redraw altered array data into image's graphics
             img_g.setColor(Color.black); 
             img_g.fillRect(0,0,50,50);
             img_g.setColor(Color.white);
             for(int r=0;r<50;r++){
                for(int c=0;c<50;c++){
                  if(array[r][c]==WHITE){
                    img_g.drawLine(r,c,r,c);
                     //draw white dots (there's no setPixel function)
                  }
		}
             }
             // "paint" the image to the main applet graphics, g
             g.drawImage(img,0,0,WIDTH,HEIGHT,this);
        }

	public void updateMsg(){
	     Color old = app_g.getColor();
	        app_g.setColor(Color.lightGray);
	        app_g.fill3DRect(0,HEIGHT,WIDTH,100,true);
	        //g.setColor(Color.black);
	        printMsg();  
	     app_g.setColor(old);
	}
	     

	public void printMsg(){
	 String str[]={"SUBMIT    this image? You can only submit once, so click SUBMIT when you're FINISHED drawing."};
	 int i = 0;
	 
	     if(cnt==1000){  // draw the SUBMIT button
		app_g.setColor(Color.darkGray);
		if(submitted==0) app_g.draw3DRect(15,260,30+SUBMIT_wid,20,true);
		else str[0] = "Sorry, you already submitted once.";
	     }
	     else{
		 if(cnt > 1000){
 		         if(cnt < 1100) str = mildly_optimistic;
		    else if(cnt < 1200) str = moderately_optimistic;
		    else if(cnt < 1300) str = optimistic;
                    else if(cnt < 1400) str = real_optimistic;
		    else if(cnt < 1500) str = very_optimistic;
		 }
		 else // less than 1000
		 {
		        if(cnt>900) str = mildly_pessimistic;
		   else if(cnt>800) str = moderately_pessimistic;
		   else if(cnt>700) str = pessimistic;
		   else if(cnt>600) str = real_pessimistic;
		   else 	    str = very_pessimistic;
		 }
 	     } 

	     int textrow = 0;
	     int begin = 0; 
	     int end = 0;
	     int lastspace = 0;

	     app_g.setColor(Color.black);
	     i = Math.abs( rand.nextInt()%str.length ); // Which of the quotes

	     while(end!=str[i].length()){
	     	for(end=begin;end<begin+30;end++){
	 	   if(end==str[i].length()) { lastspace = end; break; }
		   if(str[i].charAt(end)==' ') lastspace=end;	
		}
		app_g.drawString(str[i].substring(begin,lastspace),20,275+textrow*20);
 	        begin = lastspace+1;
		textrow++;
	     }
	}


 public void submitImage()
        {
	  int row=0;
	  int col=0;

	  for(int i=0; i<encoded.length; i++){  
	     for(int j=0; j<16; j++){ // bits encoded per int
		if(array[col][row]==WHITE) encoded[i] += two[j];	
		if(col<49){ col++;}
		else{ 	
			if(row<49) row++; 
			col=0; 
		}
	     }	
	  }

	   // turn the *special* array into a string
	   java.net.URL u = null;
           StringBuffer specialStr = 
		new StringBuffer("kpts.cgi?");
	
            for(int i=0;i<encoded.length;i++){
                specialStr.append(Integer.toString(encoded[i])+",");
	    }
 	    // create an URL object and send browser to it
            try
            {
                u = new java.net.URL(specialStr.toString());
                getAppletContext().showDocument(u);
			// showDoc...  sends browser to that URL
            }
            catch(java.net.MalformedURLException mue)
            { System.out.println(mue); }
            
	     l.setText("This is a lesson.  Not submitted.");
        }


	public void paramToArray(String param){
	  StringTokenizer st = new StringTokenizer(param,",");
	     int i=0;	
	
		for(i=0;i<encoded.length;i++){
			if(st.hasMoreTokens()) 
				encoded[i]= Integer.parseInt(st.nextToken());
			else break;
		}

		if(i!= encoded.length) System.out.println("i is"+i);

		i=0;	

		int j = 0;
	        for(int row=0;row<50;row++){
		   for(int col=0;col<50;col++){
			if((encoded[i]&two[j])>0){ 
			   array[col][row] = WHITE; 
			   encoded[i] -= two[j];
			}
			j++;
			if(j>15){ 
				j=0;
				i++;
			}
		   }
		}
        }
		
		
/***************** OPTIMISTIC COMMENTS ****************************/
String mildly_optimistic[] = {"Hmm.  I think that's too bright.", "Don't you think a bit more BLACK would be in order?" };
String moderately_optimistic[] = {"C'mon.  That's enough.  Let's see some BLACK.", "Ooh! So roseate!" };
String optimistic[] = {"This is getting so bright! How implausible.", "Feeling hopeful today, are you?" };
String real_optimistic[] = {"White, white, white--brand new fucking shiny day!", 
		            "Yeah, and I bet you think the future is aerodynamic, too, eh?" };
String very_optimistic[] = {"Well nigh 2000 points of light, but that won't do.", 
			    "Draw from life -- get some dark into this picture, won't you?" };
/**************** PESSIMISTIC COMMENTS ****************************/
String mildly_pessimistic[] = {"Too dark! Too dark! liberate your inner child!",
		"I can't see your drawing, but it must lack light." };
String moderately_pessimistic[] = {"1000. That's the rule.  You're straying into darkness!",
		"Lighter, just a touch of light. Let the sun shine through!" };
String pessimistic[] = {"Why so glum, chum?  I suggest a bit more white.",
		"Black, always black, too much black." };
String real_pessimistic[] = {"Straighten up buster, you need more light in this picture!",
		"Yeesh, it's so dark.  Couldn't you be a bit more upbeat?" };
String very_pessimistic[] = {"Well, if you mope about painting a picture that grim...", 
		"Hey, bub, look at the bright side once in a while." };

}
