> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.s-QuzKjFSbY/rev.8310
 * 
 * authors: 
 *   justin
 *   Noah Adler
 *   
 *   
 *   
 *   noah
 *   
 *   Justin Hall
 *   
 *   
 *   noah

 * license (unless otherwise specified): 
 *   creative commons attribution-share alike 3.0 license.
 *   https://creativecommons.org/licenses/by-sa/3.0/ 
 */ 




    int r=0;
    int g=0;
    int b=0;
    int a=255;
    int rad=10;
    bool locked=false;
    color currentPenColor;
    bool marker=true;
    int undos;
    bool marked=true, mouseLeft=false, buttonLock=false;
    
    var buttons = [];
    var rollbacks = [];
    var rollforwards = [];
    
    Pimage img = createImage(512, 512, RGB);

// Pressing Control-R will render this sketch.
void setup()
{  // this is run once.   
    // set the background color
    background(255);
    size(548, 512); 
    smooth();
    frameRate(30);
    noStroke();
    
    
    for(int i=0; i < img.pixels.length; i++)
    {
        img.pixels[i] = color(255); 
    }
    
    // create buttons
    
    buttons.push(new Button(2, 10, 32, color(0,0,0), color(100,0,0)));
    buttons.push(new Button(2, 47, 32, color(0,174,239), color(100,174,239)));
    buttons.push(new Button(2, 84, 32, color(105,105,108), color(205,105,108)));
    buttons.push(new Button(2, 121, 32, color(0,90,170), color(100,90,170)));
    buttons.push(new Button(2, 158, 32, color(255,255,255), color(255,255,255)));

    buttons.push(new Button(2, 358, 32, color(255,255,255), color(150,150,150), 1));
    buttons.push(new Button(2, 395, 32, color(255,255,255), color(150,150,150), 5));
    buttons.push(new Button(2, 432, 32, color(255,255,255), color(150,150,150), 10));
    buttons.push(new Button(2, 469, 32, color(255,255,255), color(150,150,150), 20));
    
    buttons.push(new Button(2, 321, 32, -1));
    buttons.push(new Button(2, 219, 32, 5));
    buttons.push(new Button(2, 261, 32, -2));

    
    
    currentPenColor=color(0);
    drawLeftBar(color(0));
} 

void draw()
{  // this is run repeatedly. 
    update(mouseX, mouseY);
    image(leftBar,0,0);
}

void drawLeftBar(color c)
{
    leftBar = createGraphics(37, 512, RGB);
    
    leftBar.beginDraw();
    leftBar.fill(255);
    leftBar.stroke(0);
    leftBar.rect(0, 1, 36, 510);
 
    for (var i=0; i<buttons.length; ++i)
        buttons[i].display();
    
    leftBar.stroke(c);
    leftBar.fill(c);
    leftBar.ellipse(18, 375, 1, 1);
    leftBar.ellipse(18, 412, 5, 5);
    leftBar.ellipse(18, 449, 10, 10);
    leftBar.ellipse(18, 486, 20, 20);
    
    leftBar.stroke(0);
    leftBar.rect(2, 321, 32, 32);
    
    leftBar.fill(0);  
    leftBar.text("undo", 5, 239);
    leftBar.text("redo", 5, 281);

    leftBar.endDraw();
    
}

void update(int x, int y)
{
  if(locked==false)
  {
    for (var i=0; i<buttons.length; ++i)
      buttons[i].update();
  } 
  else
  {
    locked=false;
  }
  
  if(mousePressed)
  {
    for(var i=0; i<buttons.length; ++i)
      if(buttons[i].pressed())
      {
      }
  }
}


class Button
{
    int x, y;
    int size;
    int radius = 0;
    color basecolor = color(255, 255, 255);
    color highlightcolor = color(155, 155, 155);
    color currentcolor = basecolor;
    boolean overInternal = false;
    boolean pressedInternal = false;
    boolean forward = false;
    boolean backward = false;
    boolean colored = false;
    boolean bucket = false;
    
// brush color button constructor    
    Button(int ix, int iy, int isize, color icolor, color ihighlight) 
    {
        x = ix;
        y = iy;
        size = isize;
        basecolor = icolor;
        highlightcolor = ihighlight;
        currentcolor = basecolor;
        colored = true;
    }
  
  // brush size button constructor
    Button(int ix, int iy, int isize, color icolor, color ihighlight, int irad) 
    {
        x = ix;
        y = iy;
        size = isize;
        basecolor = icolor;
        highlightcolor = ihighlight;
        currentcolor = basecolor;
        radius = irad;
    }

    // bucket button constructor
    Button(int ix, int iy, int isize, int n)
    {
        x = ix;
        y = iy;
        size = isize;
        if(n>0)
        {
                backward = true;
                undos = n;
        }
        else if(n==-1)
                bucket = true;
        else if(n==-2)
                forward = true;
    }
    
    void update() 
    {
        if(over())
        {
            currentcolor = basecolor;
        } 
        else
        {
            currentcolor = basecolor;
        }
  }

  boolean pressed() 
  {
    if(buttonLock==false)
    {
        if(overInternal)
        {
            if(radius!=0)
            {
                rad = radius;
                locked = true;
                marker=true;
            }
        else if(colored==true)
        {
            currentPenColor = basecolor;
            locked = true;
            drawLeftBar(basecolor);
            marker=true;
        }  
        else if(backward==true && rollbacks.length()>1)
        {
            img = rollbacks.pop();
            rollforwards.push(img);
            img = rollbacks.pop();
            rollbacks.push(img);
        }
        else if(forward==true && rollforwards.length()>0)
        {
            img = rollforwards.pop();
            rollbacks.push(img);
        }
        else if(bucket==true)
        { 
            for(int i=0; i < img.pixels.length; i++)
            {
                img.pixels[i] = color(currentPenColor); 
            }
            marked=true;
        }
        background();     
        image(img,36,0);
        buttonLock=true;
        }
      return true;
    } 
    else
    {
      locked = false;
      return false;
    }   
     
  }

  boolean overRect(int ix, int iy, int width, int height) 
  {
    if (mouseX>=ix && mouseX<=ix+width && 
      mouseY>=iy && mouseY<=iy+height)
    {
        return true;
    } 
    else
    {
        return false;
    }
  }


  boolean over() 
  {
    if(overRect(x, y, size, size))
    {
      overInternal = true;
      return true;
    } 
    else
    {
      overInternal = false;
      return false;
    }
  }

  void display() 
  {
    leftBar.stroke(0,0,0,255);
    leftBar.fill(currentcolor);
    leftBar.rect(x, y, size, size);
  }
}


void mouseDragged()
{
    stroke(currentPenColor);
    fill(currentPenColor);
    
    if(mouseX>36 && marker) // don't draw on side panel
    {
        strokeWeight(rad);
        line(mouseX, mouseY, pmouseX, pmouseY);
        strokeWeight(1);
        marked=true;
    }
}

void mouseReleased()
{
    
    buttonLock=false;
    //if we haven't just redone or undone a move
    if(buttons[8].over() == false && buttons[9].over() == false && marked == true)
    {
        marked=false;
        
        img = get(36, 0, 512, 512);    //img is a snapshot of the canvas
        if(rollbacks.length()<undos)   //we want just undos # of undos
        {
            rollbacks.push(img);        //take snapshot
            if(rollforwards.length()>0)//dump redo stack
                for(int i=0;i<rollforwards.length();i++)
                    rollforwards.pop();
        }
        else                            //if max undo limit reached,
        {                               //add one and cycle off the oldest
            for(int i=0;i<5;i++)
                rollbacks[i]=rollbacks[i+1];
            rollbacks[4]=(img);
        }
    }

}

/*
void bucketFill(int ix, int iy, color ic)
{
    set(ix, iy, currentPenColor);
    if(get(ix+1, iy)==ic && ix+1<548)
        bucketFill(ix+1, iy, ic);
    if(get(ix-1, iy)==ic && ix-1>36)
        bucketFill(ix-1, iy, ic);
    if(get(ix, iy+1)==ic && iy+1<512)
        bucketFill(ix, iy+1, ic);
    
    if(get(ix, iy-1)==ic && iy-1>0)
        bucketFill(ix, iy-1, ic);

}
*/


void mouseOver()
{
    mouseLeft=false;            //notes that the mouse is over the canvas
}

void mouseOut()
{
    mouseLeft=true;            //notes that mouse has left the canvas
}

void mouseClicked()
{
    buttonLock=true;            //locking buttons until unclicked
}

/*
void mousePressed()
{
    
    if(marker==false && mouseX>36 && get(mouseX, mouseY)!=currentPenColor)
    {
        bucketFill(mouseX, mouseY, get(mouseX, mouseY));
    }
}
*/