/**
  * Simppeli piirto-ohjelma.
  * Ikonit: http://dryicons.com
  */
  
/* Globaalit muuttujat */

public color tausta;
public color vari;
public int koko = 10;
public int maxKoko = 30;
public VariValitsin varit;
public KokoValitsin koot;
public Piirtoalue alue;
public Nappi[] napit;
public int valittu = 0;

// Pensselimoodin asetukset
public int pAlpha = 300;
public int pAlphaMin = 100;
public int pAlphaMax = 500;
public int pKokoMin = 5;
public int pKokoMax = 30;
public int pMaxNopeus = 50;

/* Alustusmedodi */

void setup(){
  size(600,500);
  frameRate(100);
  smooth();
  
  // Värit
  colorMode(HSB, 600);
  vari = color(350,600,600);
  tausta = color(200);
  background(tausta);
  
  // Luodaan kaikki tarvittava
  alue = new Piirtoalue(0,50,600,350);
  varit = new VariValitsin(0,410,600,90);
  koot = new KokoValitsin(290,10,300,maxKoko);
  
  napit = new Nappi[4];  
  napit[0] = new Nappi(0,10,8,loadImage("pencil.png"));
  napit[1] = new Nappi(1,60,8,loadImage("brush.png"));
  napit[2] = new Nappi(2,110,8,loadImage("page.png"));
  napit[3] = new Nappi(3,160,8,loadImage("trash.png"));
  
}

/* Draw-metodi jota loopataan automaattisesti */

void draw(){
  
  if(mousePressed){
     if (alue.paalla()){
       piirra();
    }
  }
  
  siistiReunat();
 
  varit.paivita();
  koot.paivita();
  
  for (int i = 0; i < napit.length; i++) {
    napit[i].paivita();   
  }
}

/* Piirtotyökalu */

void piirra(){
  stroke(vari);
  
  switch(valittu){
    case 1: // sivellin
    sivellinSaadot();
    break;
    case 2: // kumi
    stroke(600);
    break;
  }
  
  strokeWeight(koko);
  line(mouseX, mouseY, pmouseX, pmouseY);
  
}


/* Experimental: Sivellinmoodi
 * Säätää siveltimen kokoa ja alphaa hiiren nopeuden mukaan 
 */

void sivellinSaadot(){
     
  // Lasketaan hiiren nopeus
  float nopeus = float(abs(mouseX-pmouseX)+abs(mouseY-pmouseY));
      
  // Rajoitetaan nopeus välille 0-pMaxNopeus
  nopeus = constrain(nopeus,0,pMaxNopeus);
  
  // Mapataan nopeus koko-arvoksi sallitulle välille
  koko = int(map(nopeus, 0, pMaxNopeus, pKokoMin, pKokoMax)); 
       
  // Mapataan nopeus alpha-arvoksi sallitulle välille
  int a = int(map(nopeus, 0, pMaxNopeus, pAlphaMin, pAlphaMax)); 
  
  // Katsotaan ettei alpha-arvo eroa turhan paljon edellisestä arvosta
  int erotus = constrain(a-pAlpha,-5,5);
  pAlpha = pAlpha + erotus;
  stroke(vari,pAlpha);
}

/* Poistaa jäljet piirtoalueen ulkopuolelta */

void siistiReunat(){
  noStroke();
   fill(tausta);
   rect(0, 0, 600, 50);
   rect(0, 400, 600, 10);
}

/* Yläluokka kaikille painettaville objekteille */

class Painettava {
  int x,y,l,k;
   
  public boolean paalla(){
     if (mouseX >= x && mouseX <= x+l && 
        mouseY >= y && mouseY <= y+k) {
      return true;
    } else {
      return false;
    }
   } 
   
   public void paivita(){
     if (this.paalla() && mousePressed){
        this.valitse();
      }
      this.piirra();
   }
   
   // Alaluokat toteuttavat metodit
   public void valitse(){
   }
   public void piirra(){
   }
}

class Piirtoalue extends Painettava {
  Piirtoalue(int ix,int iy,int il,int ik){
    x = ix;
    y = iy;
    l = il;
    k = ik;
    
    this.tyhjenna();
  }
  
  void tyhjenna(){
    noStroke();
    fill(600);
    rect(x, y, l, k);
  }
}

class Nappi extends Painettava {
  
  //boolean paalla = false;
  //boolean painettu = false;
  PImage kuva;
  int tehtava;
  int e = 3; // valittu-laatikon padding
  
  Nappi(int itehtava, int ix, int iy, PImage ikuva){
    x = ix;
    y = iy;
    kuva = ikuva;
    l = 32;
    k = 32;
    tehtava = itehtava;
  }
  
  void valitse(){
    if (this.tehtava == 3){
      alue.tyhjenna();
    } else{
    valittu = this.tehtava;
    }
  }
  
  void piirra(){
    if (valittu == this.tehtava){
      fill(100);
      noStroke();
      rect(x-e,y-e,l+2*e,k+2*e);
    }
    image(kuva,x,y);
  }
  
}

class KokoValitsin extends Painettava {
  
  public KokoValitsin(int ix,int iy,int il,int ik){
    x = ix;
    y = iy;
    l = il;
    k = ik;
  }
  
  public void valitse(){
    koko = int(map(mouseX-x,0,l,0,k));
  }
  
  public void piirra(){
     
    noStroke();
    fill(tausta);
    rect(x,y,l,k);
    
    fill(300);
    triangle(x,y+k,x+l,y+k,x+l,y);
    
    int val = int(map(koko,0,k,0,l));
    
    fill(vari);
    triangle(x,y+k,x+val,y+k,x+val,y+k-koko);
    
    //fill(0);
    //triangle(val-5, y+k, val+5, y+k, val, y+k-10);  

  }
}


class VariValitsin extends Painettava {
  
  /* Generoi värilivalitsimen */  
  
  public VariValitsin(int ix,int iy,int il,int ik){
    x = ix;
    y = iy;
    l = il;
    k = ik;
    
    for (int i = 0; i < l; i++) {
      stroke(i, l, l);
      strokeWeight(1);
      line(i,y+10,i,y+k);
    }
    
    this.paivita();
  }
  
  public void valitse(){
     vari = color(mouseX,l,l);
  }

  public void piirra(){
    
    noStroke();
    // Peitetään vanha marker
    fill(tausta);
    rect(x,y,l,10);
    
    // Piirretään uusi
    int val = int(hue(vari));
    fill(0);
    triangle(val-5, y, val+5, y, val, y+10);
  }
}

