> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.oi8XEHkx$qm/rev.8062
 * 
 * authors: 
 *   
 *   KonkaNok
 *   
 *   
 *   Stuart
 *   
 *   greg
 *   
 *   Liam Humphreys
 *   joey ciechanowicz
 *   KonkaNok
 *   
 *   

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



// 24 hour
Graph graph;
ArrayList blocks = new ArrayList();

// timestamps
int d = 15; // affects the range in hours
int[] x_values = {
  1331821200, 1331821260, 1331821320, 1331821380, 1331821440 };
int[] y_values = { 4642, 1623, 1280, 358, 1381};

void setup() {
  size(800, 400);
  frameRate(60);
  fill(0); 

  //PFont myFont = createFont("DejaVuSansCondensed-Bold-48", 12);
 // textFont(myFont);

  Series series2 = new Series(x_values, y_values);
  Plot p2 = new Plot(series2);

  graph = new Graph(width, height);
  graph.addPlot(p2);
}

void draw() {
  background(255);  
  graph.display();
} 

class Series {
  int x_values[], y_values[];
  int min_x, min_y, max_x, max_y;
  int length;

  Series(int x_[], int y_[]) {
        x_values = x_;
        y_values = y_;
        length = x_values.length;
  }
}

class Graph {
  //  Series s;
  XAxis x_axis;
  YAxis y_axis;
  ArrayList plots = new ArrayList();
  int x, y, graph_w, graph_h, block_width;

  Graph(int w_, int h_) {
        graph_w = w_;
        graph_h = h_;
        x = 50;
        y = graph_h - 50;
  }

  void generateAxes(int start, int end) {
        x_axis = new XAxis(start, end);
        y_axis = new YAxis();
  }

  void addPlot(Plot p) {  
        generateAxes(min(p.data.x_values), max(p.data.x_values));
        p.graph_h = graph_h;
        p.graph_w = graph_w;
        p.generateBlocks();
        plots.add(p);
  }

  void display() {
        for (int i=0;i<plots.size();i++) {
          Plot p = (Plot) plots.get(i);
          p.display();
        }

        x_axis.display();
        y_axis.display();
  }

  // Tick class
  class Tick {
        int x;
        String label; 
        boolean hide = false;

        Tick(int x_, String label_) {
          x = x_;
          label = label_;
        }
  }

  class XAxis {
        // positioning
        int origin_x, origin_y, end_x, end_y, len;
        Tick ticks[];
        int range_start = 0, range_end = 0;
        float range = 0; // in hours    
        int no_ticks = 12;
        int interval = 1800; 

        XAxis(int start, int end) {
          // default is 6 ticks
          origin_x = 50;
          origin_y = graph_h-50;
          end_x = graph_w-50;
          end_y = graph_h-50;
          range_start = start;
          range_end = end;
          len = end_x - origin_x;

          range = ((range_end - range_start) / 7200)+1;
          int tick_mult = 7200 / interval;       

          if (interval == 1800)
                range *=4;

          if (interval == 3600)
                range *= 2;

          ticks = new Tick[(int)range * tick_mult];
          generateLabels();
        }

        void generateLabels() {

          int no_hours = range_start / 3600;
          no_hours = no_hours * 3600;
          int offset = (no_hours + interval) - range_start;

          for (int i=0;i<range;i++) {       
                int epoch =  range_start + (i*interval) + offset; // two hour interval
                //        println("time: " + getLabel(epoch));
                int tick_x = plotOnXAxis(epoch);
                ticks[i] = new Tick(tick_x, getLabel(epoch));

                //        if(ticks[i].x < origin_x)
                //          ticks[i].hide = true;
                println("tick " + i + ": " + ticks[i].x +", " + ticks[i].label);
          }
        }

        int plotOnXAxis(float epoch) {   
          int len = graph_w-100; // sort out custom length
          float result = ((epoch - range_start) / (range_end - range_start)) * len;
          return (int) result;
        }

        String getLabel(int epoch) {
         
          return "test";
        }

        void display() {
          // draw axis
          stroke(0);
          fill(0);
          strokeWeight(3.0);
          line(origin_x, origin_y, end_x, end_y); // base line
          int tick_interval = len / 6; // there are 7 ticks
          int offset = 35;

          for (int i=0;i<range;i++) {
                if (!ticks[i].hide)
                  text(ticks[i].label, ticks[i].x + offset, origin_y+20);
                line(ticks[i].x + 50, origin_y, ticks[i].x + 50, origin_y + 5);
          }
        }
  }


  class YAxis {
        int origin_x, origin_y;
        int end_x, end_y, len;
        int no_ticks = 6;
        Tick ticks[] = new Tick[no_ticks+1];
        int range_start = 0, range_end = 12000;

        YAxis() {
          no_ticks = 6;
          origin_x = 50;
          origin_y = graph_h - 50;
          end_x = 50;
          end_y = graph_h - (graph_h - 50);
          len = origin_y - end_y;
          generateLabels();
        }

        void generateLabels() {
          for (int i=0;i<7;i++) {
                int val = (i * 2) * 1000;
                int tick_y = plotOnYAxis(val);
                ticks[i] = new Tick(tick_y, getLabel(val));
          }
        }

        int plotOnYAxis(float epoch) {   
          int len = graph_h-100; // sort out custom length
          float result = graph_h - ((epoch - range_start) / (range_end - range_start)) * len;
          return (int) result;
        }

        String getLabel(int val) {
          String energy = (val / 1000) + "kW";
          return energy;
        }

        void display() {
          // draw axis
          stroke(0);
          strokeWeight(3.0);
          line(origin_x, origin_y, end_x, end_y);
          int tick_interval = len / no_ticks;

          for (int i=0;i<no_ticks+1;i++) {
                line(origin_x, ticks[i].x - 50, origin_x - 5, ticks[i].x - 50);
                text(ticks[i].label, origin_x-40, ticks[i].x - 50);
          }

          //      Plot p = (Plot) plots.get(0);
          //      float diff = 1000000;
          //      int index = 0;
          //      for(int i=0;i<p.data.length;i++) {
          //        if(mouse_x == p.blocks[i].x)
          //          ellipse(p.blocks[i].x, 400);
          //      }
          //      ellipse(p.blocks[index].x+50, p.blocks[index].y-50, 4, 4);
          //      text("value: " + p.blocks[index].y, 100, 100);
          //      println("pointX: " + (p.blocks[index].x+50) + " | pointY: " + (p.blocks[index].y));
          //      println("mouseX: " + mouseX + " | mouseY: " + mouseY);

          int mouse_x = mouseX;
          if (mouse_x < x_axis.origin_x)
                mouse_x = x_axis.origin_x;

          if (mouse_x > x_axis.end_x)
                mouse_x = x_axis.end_x;

          strokeWeight(2.0);
          stroke(color(255, 0, 0), 100);
          line(mouse_x, y_axis.origin_y, mouse_x, y_axis.end_y);
        }
  }
}

class Plot {
  Series data;
  Block blocks[];
  int range_start = 1331802000, range_end = 1331845200;
  int yrange_start = 0, yrange_end = 12000, graph_h = 0, graph_w = 0;
  color fil = color(255, 0, 0);

  Plot(Series data_) {
        data = data_;
        range_start = min(data.x_values);
        range_end = max(data.x_values);
        blocks = new Block[data.length];
        //    generateBlocks();
  }

  void generateBlocks() {
        for (int i=0;i<data.length;i++) {
          int x = plotOnXAxis(data.x_values[i]);
          int y = plotOnYAxis(data.y_values[i]);// * (-300 / max(y_values));
          int w = 10, h = 10;
          blocks[i] = new Block(x, y, y_values[i]);
          //      println("x: " + x + " y: " + y);
        }
  }

  int plotOnXAxis(float epoch) {   
        int len = graph_w - 100; // sort out custom length
        float result = ((epoch - range_start) / (range_end - range_start)) * len;
        //    println(getLabel((int)epoch));
        return (int) result;
  }

  String getLabel(int epoch) {
      
        return "test";
  }

  int plotOnYAxis(float energy) {   
        int len = graph_h - 100; // sort out custom length
        float result = graph_h - ((energy - yrange_start) / (yrange_end - yrange_start)) * len;
        return (int) result;
  }

  void setCol(color c) {
        for (int i=0;i<data.length;i++)
          fil = c;
  }

  void display() {   
        for (int i=0;i<data.length;i++) {
          blocks[i].display();
          if (i < data.length-1) {
                strokeWeight(3.0);
                stroke(fil); // affects fillshape outline
                line(blocks[i].x+50, blocks[i].y-50, blocks[i+1].x+50, blocks[i+1].y-50);
          }
        }

        fill(fil, 100);
//    strokeWeight(1.0);
//    stroke(#007915,0);

        // fill shape

        beginShape();    
         vertex(50, height-50);     
         for (int i=0;i<data.length;i++) {      
         vertex(blocks[i].x+50, blocks[i].y-50);
         }
         vertex(blocks[data.length-1].x+50, height-50);
         endShape();


  }
  // Block class

  class Block {
        int x, y, w, h, val;    
        color outline = color(255, 0, 0);

        Block(int x_, int y_, int val_) {
          x = x_;
          y = y_;
          val = val_;
        }

        void display() {
          smooth();
//      stroke(#007915);
          fill(#007915);
//      strokeWeight(2.0);]
          // bars
          rectMode(CORNER);
//      ellipse(x+50, y-50, 2, 2);     
        }
  }
}