import processing.core.*; 
import processing.xml.*; 

import java.applet.*; 
import java.awt.*; 
import java.awt.image.*; 
import java.awt.event.*; 
import java.io.*; 
import java.net.*; 
import java.text.*; 
import java.util.*; 
import java.util.zip.*; 
import java.util.regex.*; 

public class WebPaint extends PApplet {

int dotNum;
int radius;
int xNum, yNum;
int distance;
int startX,startY;
int clearX,clearY;
int buttonWidth,buttonHeight;
float angle;
float rad;
float tempX,tempY;
Dot[] Dots;
PImage bg;
boolean startButton = false;
boolean clearButton = false;
boolean startOver = false;
boolean clearOver = false;
boolean direction = false;
int tempDotsNum;
public void setup(){
  size(600,600);
  smooth();
  noStroke(); 
  frameRate(60);

  bg = loadImage("background.jpg");
  image(bg,0,0);

  //the preference of DOTS
  distance = 15; 
  radius  = 4;
  dotNum = 0;
  tempX = 0;
  tempY = 0;

  startX = 200;
  startY = 570;
  clearX = 300;
  clearY = 570;
  buttonWidth = 100;
  buttonHeight = 30;
  
  //Calculate the number of dots
  angle = 18.0f;
  rad = radians(angle);
  xNum = PApplet.parseInt((width*cos(rad) + height*sin(rad))/distance) + 1;
  yNum = PApplet.parseInt((width*sin(rad) + height*cos(rad))/distance) + 1;

  //the coordinate of points
  Dots = new Dot[xNum*yNum];
  for( int i = 0; i < xNum*yNum; i ++){
    Dots[i] = new Dot( tempX, tempY, radius);
  }
  loadPoints();
}

public void draw(){
  update(mouseX,mouseY);
  if(startButton == true){
    if(direction){
      if(tempDotsNum <= dotNum - 1 && Dots[tempDotsNum].tempRadius != Dots[tempDotsNum].radius){
        Dots[tempDotsNum].increase();
      }
      else if(tempDotsNum < dotNum - 1 && Dots[tempDotsNum].tempRadius == Dots[tempDotsNum].radius){
        tempDotsNum ++;
      }
      else if(tempDotsNum == dotNum - 1 && Dots[tempDotsNum].tempRadius == Dots[tempDotsNum].radius){
        direction = false;
      }
    }
    else{
      if(tempDotsNum >= 0 && Dots[tempDotsNum].tempRadius != 4){
        Dots[tempDotsNum].decrease();
      }
      else if(tempDotsNum > 0 && Dots[tempDotsNum].tempRadius == 4){
        tempDotsNum --;
      }
      else if(tempDotsNum == 0 && Dots[tempDotsNum].tempRadius == 4){
        direction = true;
      }
    }
  }     
}

class Dot {
  float x,y;
  int radius;
  int tempRadius;

  Dot(float tempX, float tempY, int r) {
    x = tempX;
    y = tempY;
    radius = r;
    tempRadius = 4;
  }

  public void reShape(){
    fill(255);
    ellipse(x,y,radius,radius);
  }

  public void decrease(){
    tempRadius --;
    fill(0);
    ellipse(x,y,distance,distance);
    fill(255);
    ellipse(x,y,tempRadius,tempRadius);
  }  

  public void increase(){
    fill(255);
    tempRadius ++;
    ellipse(x,y,tempRadius,tempRadius);
  }    
}

public void update(int x, int y)
{
  if( overStart(startX, startY, buttonWidth, buttonHeight) ) {
    startOver = true;
    clearOver = false;
  } else if ( overClear(clearX, clearY, buttonWidth, buttonHeight) ) {
    clearOver = true;
    startOver = false;
  } else {
    startOver = clearOver = false;
  }
}
public void mouseDragged(){
  fill(255,255,255,240);

  int dotX, dotY; // the position to the rotated coordinate
  float pointX, pointY; //the position to the original coordinate

  dotX = PApplet.parseInt(((sin(rad)*mouseY + cos(rad)*mouseX)+distance/2)/distance)*distance;
  dotY = PApplet.parseInt(((width*sin(rad) - mouseX*sin(rad) + mouseY*cos(rad))+distance/2)/distance)*distance;

  pointX = dotX*cos(rad) - dotY*sin(rad) + width*sin(rad)*sin(rad);
  pointY = dotY*cos(rad) + dotX*sin(rad) - width*sin(rad)*cos(rad);

  if(pointX != tempX){
    Dots[dotNum].x = pointX;
    Dots[dotNum].y = pointY;
    tempX = pointX;
    tempY = pointY;
    tempDotsNum = dotNum;
    dotNum ++;

  }
  else if(Dots[tempDotsNum].radius < distance){
    Dots[tempDotsNum].radius ++;
    Dots[tempDotsNum].tempRadius = Dots[tempDotsNum].radius;
    Dots[tempDotsNum].reShape();
  }
}

public void mousePressed()
{
  if(startOver) {
    startButton = true;
  }
  if(clearOver) {
    startButton = false;
    image(bg,0,0);
    for( int i = 0; i < Dots.length; i ++){
      Dots[i].radius = 4;
    }
    dotNum = 0;
    tempDotsNum = 0;
    direction = false;
  }
}

public boolean overStart(int x, int y, int width, int height) 
{
  if (mouseX >= x && mouseX <= x+width && 
      mouseY >= y && mouseY <= y+height) {
    return true;
  } else {
    return false;
  }
}

public boolean overClear(int x, int y, int width, int height) 
{
  if (mouseX >= x && mouseX <= x+width && 
      mouseY >= y && mouseY <= y+height) {
    return true;
  } else {
    return false;
  }
}

public void loadPoints(){
  float data[] = new float[3];
  String[] points = loadStrings("points.txt");
  dotNum = points.length;
  for( int i = 0; i < dotNum; i ++){
    data = PApplet.parseFloat( split(points[i],','));
    Dots[i].x = data[0];
    Dots[i].y = data[1];
    Dots[i].radius = PApplet.parseInt(data[2]);
  }
  startButton = true;
  direction = false; 
  for( tempDotsNum=0; tempDotsNum<= dotNum-1; tempDotsNum++){
    Dots[tempDotsNum].tempRadius = Dots[tempDotsNum].radius;
    Dots[tempDotsNum].reShape();
  }
}

  static public void main(String args[]) {
    PApplet.main(new String[] { "WebPaint" });
  }
}
