import processing.core.*; 
import processing.data.*; 
import processing.event.*; 
import processing.opengl.*; 

import java.util.HashMap; 
import java.util.ArrayList; 
import java.io.File; 
import java.io.BufferedReader; 
import java.io.PrintWriter; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.io.IOException; 

public class SignatureGernerator1_1 extends PApplet {

ArrayList<buttonClass> buttonslist = new ArrayList<buttonClass>();

int d1, d2, m1, m2, y1, y2, m, d, y;
PImage[] numberImages = new PImage[12];
//PImage[]numberImages = new PImage[12];
PImage[] signatures  = new PImage[6];
PImage slash, slash2, signature, ssignature; 
PImage bgImage; 
PGraphics alphaG, salphaG, emptySig;
boolean skinny = true;  
PFont font; 
int monthX, dayX, yearX, monthW, dayW, yearW; 
int textcounter = 0; 

long snapTimer; 
int snapInterval = 3000; 
int fade; 
int signatureNum = 0; 
boolean showDate = true; 
int wiggleRoom = 50; 
boolean scaleBoolean = false; 
int startscale; 
boolean mouseFlag; 
int endOfDate; 
int heightWiggle = 0; 
boolean setbackground; 
int totalSigs; 
/// 

PImage destination, holdimage, outputImage;  
int c, newpix;
boolean click, knob, click2, knob2; 
float alphaKnob = 200; 
float contrastKnob = 150; 
boolean enableAlpha = false; 
boolean enableContrast; 
boolean showSig = true; 
///
StringList sigFileNames; 
ArrayList<PImage> signatureImages = new ArrayList<PImage>(); 
File dir; 
File [] files;
PImage p1; 


public void setup() {
  
  buttonslist = new ArrayList();
  for (int i = 0; i < 6; i ++) {
    buttonslist.add(new buttonClass((i* 200)+60, height - 30, 180, 30, i));
  }
  font = createFont("helvetica", 12); 
  textFont(font); 
  alphaG = createGraphics(width, height); 
  salphaG = createGraphics(width, height); 

  numberImages[0] = loadImage("numbers/zero.png");
  numberImages[1] = loadImage("numbers/one.png");
  numberImages[2] = loadImage("numbers/two.png");
  numberImages[3] = loadImage("numbers/three.png");
  numberImages[4] = loadImage("numbers/four.png");
  numberImages[5] = loadImage("numbers/five.png");
  numberImages[6] = loadImage("numbers/six.png");
  numberImages[7] = loadImage("numbers/seven.png");
  numberImages[8] = loadImage("numbers/eight.png");
  numberImages[9] = loadImage("numbers/nine.png");
  numberImages[10] = loadImage("numbers/slash.png");
  numberImages[11] = loadImage("numbers/slash2.png");

  autoimport(); 

  d = day();    
  m = month();  
  y = year();
  snapTimer = millis() - snapInterval;
bgImage = loadImage("checker.jpg"); 
}

public void draw() {
  background(255); 
  image(bgImage, 0, 0); 
  //if (signatureNum != 4) {
    alphaContrast();
  //}
  d1 = d/10; 
  d2 = d%10; 
  m1 = m/10; 
  m2 = m%10; 
  int joeY = y - 2000; 
  y1 = joeY/10; 
  y2 = joeY%10; 

  int locX = 10;

  if (showSig == true) {
    if (enableAlpha) {
      image(destination, locX, height/2 - destination.height/2);
    } else { 
      image(signatureImages.get(signatureNum), locX, height/2 - signatureImages.get(signatureNum).height/2);
    }
  }

  locX += signatureImages.get(signatureNum).width + wiggleRoom; 
  monthX = locX; 

  if (showDate) {
    image(numberImages[m1], locX, (height/2 -numberImages[m1].height/2) + heightWiggle); 
    locX +=numberImages[m1].width; 
    image(numberImages[m2], locX, (height/2 -numberImages[m2].height/2 ) + heightWiggle);
    locX +=numberImages[m2].width; 
    image(numberImages[10], locX, (height/2 -numberImages[10].height/2) + heightWiggle); // slash
    locX +=numberImages[10].width; 
    dayX = locX;
    image(numberImages[d1], locX, (height/2 -numberImages[d1].height/2) + heightWiggle);
    locX +=numberImages[d1].width; 
    image(numberImages[d2], locX, (height/2 -numberImages[d2].height/2) + heightWiggle);
    locX +=numberImages[d2].width; 
    image(numberImages[11], locX, (height/2 -numberImages[11].height/2) + heightWiggle); // slash
    locX +=numberImages[11].width; 
    yearX = locX;
    image(numberImages[2], locX, (height/2 -numberImages[2].height/2) + heightWiggle);
    locX +=numberImages[2].width; 
    image(numberImages[0], locX, (height/2 -numberImages[0].height/2) + heightWiggle);

    locX +=numberImages[0].width; 
    image(numberImages[y1], locX, (height/2 -numberImages[y1].height/2) + heightWiggle);
    locX +=numberImages[y1].width; 

    image(numberImages[y2], locX, (height/2 -numberImages[y2].height/2) + heightWiggle);
    endOfDate = locX + numberImages[y2].width + 30;
  }
  locX +=numberImages[y2].width; 

  image(salphaG, 0, 0);
  fill(255); 

  int st = signatureImages.get(signatureNum).width; 
  line(st, 20, st, 100); 
 // rect(st-4, 40 + heightWiggle, wiggleRoom +8, 20); 
  line(st,  50 + heightWiggle , st + wiggleRoom,  50 + heightWiggle); 
  if (scaleBoolean) {
    fill(1);
  }
  triangle(st, 50 + heightWiggle, st + 10, 45 + heightWiggle, st + 10, 55 + heightWiggle); 
  triangle(st + wiggleRoom, 50 + heightWiggle, st + wiggleRoom -10, 45 + heightWiggle, st + wiggleRoom -10, 55 + heightWiggle); 

  monthW =numberImages[m1].width +numberImages[m2].width; 
  dayW =numberImages[d1].width +numberImages[d2].width; 
  yearW =numberImages[y1].width +numberImages[y2].width +numberImages[2].width +numberImages[0].width;

  fill(0); 
  textFont(font, 16); 
  text("Signature Generator", 20, 20);
  textFont(font, 16); 
  if (textcounter > 0 ) {
    textcounter --; 
    text("Signature Saved", width - 700, 20);
  }
  textFont(font, 20); 

  if (millis() - snapTimer < snapInterval) {
    if (fade > 0) {
      fade -- ;
    }
    fill(255, fade); 
    rect (0, 0, width, height);
    fill(30, 70, 180); 
    text("saving signature and date into output folder", width - 720, 20);
  }

  if (scaleBoolean) {
    setbackground = true; 
    heightWiggle += mouseY - pmouseY;
    heightWiggle = constrain(heightWiggle, -20, 50);
    wiggleRoom += mouseX - pmouseX; 
    wiggleRoom = constrain(wiggleRoom, 30, 400);
  }

  for (int i = buttonslist.size()-1; i >= 0; i--) { 
    buttonClass dbutton = buttonslist.get(i); 
    dbutton.display();
  }

  drawKnobs();
}

public void mousePressed() {
  
 // int st = signatureImages.get(signatureNum).width; 
  //line(st, 20, st, 100); 
  //rect(st-4, 40 + heightWiggle, wiggleRoom +8, 20); 
  
  if ( mouseY < 60  + heightWiggle && mouseY > 40 + heightWiggle  && mouseX >signatureImages.get(signatureNum).width 
    && mouseX < signatureImages.get(signatureNum).width + 30 + wiggleRoom) {
    scaleBoolean = true;
  }


  if (dist(mouseX, mouseY, alphaKnob, 40) < 10) {
    knob = true;
  }

  if (dist(mouseX, mouseY, 20, 40) < 10) {
    enableAlpha = !enableAlpha;
    //destination = signatureImages.get(signatureNum); 
    //destination.updatePixels();
  }
  if (dist(mouseX, mouseY, contrastKnob, 60) < 10) {
    knob2 = true;
  }
}

public void mouseReleased() {
  scaleBoolean = false; 
  if ( mouseY < height/2 && mouseY > height/2 - 40) {
    if (mouseX > monthX && mouseX < monthX + monthW) {
      m ++;
      if (m > 12) {
        m = 1;
      }
    }
    if (mouseX > dayX && mouseX < dayX + dayW) {
      d ++;
      if (d > 31) {
        d = 1;
      }
    }
    if (mouseX > yearX && mouseX < yearX + yearW) {
      y ++;
    }

    //alphaG = createGraphics(width, height); 
    salphaG = createGraphics(width, height);
  }

  if ( mouseY > height/2 && mouseY < height/2 + 40) {
    if (mouseX > monthX && mouseX < monthX + monthW) {
      m --;
      if (m < 1) {
        m = 12;
      }
    }
    if (mouseX > dayX && mouseX < dayX + dayW) {
      d --;
      if (d <1) {
        d = 31;
      }
    }
    if (mouseX > yearX && mouseX < yearX + yearW) {
      y --;
    }
    salphaG = createGraphics(width, height);
  }


  knob = false;
  knob2 = false;
}

public void keyPressed() {
  if (key == 's') {
    signatureNum ++;
    if (signatureNum >= totalSigs) {
      signatureNum = 0;
    }
  }

  if (keyCode == 10) {
    snapTimer = millis(); 
    fade = 255; 
    makeGraphic();
  }
}


class buttonClass {
  int xloc, yloc, w, h, num;  // declare the variables used in the class
  int counter = 200; 
  buttonClass(int _x, int _y, int _w, int _h, int _num) { 
    xloc = _x; // assign incoming temporary values to the variables you set above. 
    yloc = _y;
    w = _w; 
    h = _h; 
    num = _num;
  }

  public void display() {
    noFill(); 
    fill(200, 200);
    //if (num == 0 && enableAlpha) {
    //  fill(140, 100, 100, 200);
    //}
        if (num == 5) {
      fill(180, 180, 240, 200);
    }
    
    if (mouseX > xloc && mouseX < xloc + w && mouseY > yloc && mouseY < yloc + h) {
      fill(140, 200);
 if (num == 5) {
      fill(120, 120, 180, 200);
    }

      if (mousePressed && mouseFlag == false) {
        //salphaG.background(255);
        mouseFlag = true; 
        //println(num);
        if (num == 0) {
          enableAlpha = !enableAlpha;
        }
        if (num == 1) {
          showSig = !showSig;
        }
        if (num == 4) {
          showDate = !showDate;
          setbackground = true;
        }
        if (num == 2) {
          signatureNum ++;
          if (signatureNum >= totalSigs) {
            signatureNum = 0;
          }
          setbackground = true; 
          destination = createImage(signatureImages.get(signatureNum).width, signatureImages.get(signatureNum).height, RGB);

        }
        if (num == 3) {
          d = day(); 
          m = month(); 
          y = year();
          setbackground = true;
        }
        if (num == 5) {
          snapTimer = millis(); 
          fade = 255; 
          //salphaG.save("output/signature" + d + m + y + ".png");
          makeGraphic();
        }
      }
      if (mousePressed == false) {
        mouseFlag = false;
      }
    }
    noStroke(); 
    rect(xloc, yloc, w, h);
    fill(1);
    textFont(font, 16); 
    switch(num) {
    case 0: 
      text("Background/contrast", xloc + 10, yloc + 26); 
      break;
    case 1: 
      text("Show/hide signature", xloc + 10, yloc + 26); 
      break;
    case 4: 
      text("Show/hide date", xloc + 10, yloc + 26); 
      break;
    case 2: 
      text("Change Signature", xloc + 10, yloc + 26); 
      break;
    case 3: 
      text("Reset to Today", xloc + 10, yloc + 26); 
      break;
    case 5: 
      text("Make Image", xloc + 10, yloc + 26); 
      break;
    }
    stroke(1);
  }
}
public void alphaContrast() {

  if (enableAlpha) {
    signatureImages.get(signatureNum).loadPixels();
    destination.loadPixels();  

    for (int i = 0; i < signatureImages.get(signatureNum).width; i ++) {
      for (int j = 0; j < signatureImages.get(signatureNum).height; j ++) {
        c= signatureImages.get(signatureNum).get(i, j); 
        int d = c; 
        //if (enableAlpha) {
        if (brightness(c) > alphaKnob - 50) {
          c = color(red(c), green(c), blue(c), 1);
        } else {
          c = color(red(c) - contrastKnob/4, green(c) - contrastKnob/4, blue(c) - contrastKnob/4);
        }
        //}
        //else{
        //  c = color(red(c), green(c), blue(c), alpha(c)); 
        //}

        destination.set(i, j, c);
        signatureImages.get(signatureNum).set(i, j, d); 
        //}
      }
    }
    destination.updatePixels();
    signatureImages.get(signatureNum).updatePixels();
  }
}

public void drawKnobs() {
  if (enableAlpha) {
    fill(255); 
    if (knob) {
      //alphaKnob += mouseX-pmouseX; 
      alphaKnob = mouseX; 
      alphaKnob = constrain(alphaKnob, 50, 350);
      fill(180);
    }
    line(50, 40, 350, 40); 
    ellipse(alphaKnob, 40, 16, 16); 
    fill(255); 
    if (knob2) {
      contrastKnob = mouseX; 
      contrastKnob = constrain(contrastKnob, 50, 350);
      fill(180);
    }
    line(50, 60, 350, 60);
    ellipse(contrastKnob, 60, 16, 16);
    
  }
  //fill(255); 
  //ellipse(20, 40, 20, 20); 
  //if (enableAlpha) {
  //  fill(1); 
  //  ellipse(20, 40, 10, 10);
  //}
}
public void autoimport(){
  sigFileNames = new StringList(); 
  dir= new File(sketchPath("signature")); 
  files= dir.listFiles();
  for (int i = 0; i < files.length; i++)   
  {
    String path = files[i].getPath(); // .getAbsolutePath();
    if (path.toLowerCase().endsWith(".jpeg") || path.toLowerCase().endsWith(".jpg")
    || path.toLowerCase().endsWith(".png") || path.toLowerCase().endsWith(".gif")) {
      //int p3 = sigFileNames.indexOf("._");
      if(path.contains("._") == false){ // avoids invisible files problem
      sigFileNames.append(path);
      }
    }
  
  }

  for (int i = 0; i <= sigFileNames.size() - 1; i++)   
  {
    p1 = loadImage(sigFileNames.get(i));
    signatureImages.add(p1);
  }
  p1 = signatureImages.get(0); 
  destination = createImage(p1.width, p1.height, RGB);
  //destination = p1; 
  
  totalSigs = signatureImages.size(); 
}
public void makeGraphic() {

  int locX = 10;
 // outputImage = createImage(width, height, RGB);
  alphaG = createGraphics(width, height); 
  alphaG.beginDraw();
  alphaG.smooth(); 
  if (showSig == true) {
    if (enableAlpha) {
      alphaG.image(destination, locX, height/2 - destination.height/2);
    } else { 
      alphaG.image(signatureImages.get(signatureNum), locX, height/2 - signatureImages.get(signatureNum).height/2);
    }
  }
  locX += destination.width + wiggleRoom; 
  monthX = locX; 

  if (showDate) {
    alphaG.image(numberImages[m1], locX, (height/2 -numberImages[m1].height/2) + heightWiggle); 
    locX +=numberImages[m1].width; 
    alphaG.image(numberImages[m2], locX, (height/2 -numberImages[m2].height/2 ) + heightWiggle);
    locX +=numberImages[m2].width; 
    alphaG.image(numberImages[10], locX, (height/2 -numberImages[10].height/2) + heightWiggle); // slash
    locX +=numberImages[10].width; 
    dayX = locX;
    alphaG.image(numberImages[d1], locX, (height/2 -numberImages[d1].height/2) + heightWiggle);
    locX +=numberImages[d1].width; 
    alphaG.image(numberImages[d2], locX, (height/2 -numberImages[d2].height/2) + heightWiggle);
    locX +=numberImages[d2].width; 
    alphaG.image(numberImages[11], locX, (height/2 -numberImages[11].height/2) + heightWiggle); // slash
    locX +=numberImages[11].width; 
    yearX = locX;
    alphaG.image(numberImages[2], locX, (height/2 -numberImages[2].height/2) + heightWiggle);
    locX +=numberImages[2].width; 
    alphaG.image(numberImages[0], locX, (height/2 -numberImages[0].height/2) + heightWiggle);

    locX +=numberImages[0].width; 
    alphaG.image(numberImages[y1], locX, (height/2 -numberImages[y1].height/2) + heightWiggle);
    locX +=numberImages[y1].width; 

    alphaG.image(numberImages[y2], locX, (height/2 -numberImages[y2].height/2) + heightWiggle);
    endOfDate = locX + numberImages[y2].width + 30;
  }
  locX +=numberImages[y2].width; 
  alphaG.endDraw();
  alphaG.save("output/signature" + d + m + second() + ".png");
}
  public void settings() {  size(1300, 220); }
  static public void main(String[] passedArgs) {
    String[] appletArgs = new String[] { "SignatureGernerator1_1" };
    if (passedArgs != null) {
      PApplet.main(concat(appletArgs, passedArgs));
    } else {
      PApplet.main(appletArgs);
    }
  }
}
