> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.uRuUEfs5FlG/rev.1793
 * 
 * authors: 
 *   open architecture open design

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



//goal: drawing and calculating 2d trusses, testing sketchpad...
//UI: spacebar switches between drawing and editing mode
//in drawing mode:
//left mouse button to add a node
//right mouse button to add a member between two nodes
//in editing mode:
//left mouse button to drag the node

ArrayList nodes;
ArrayList members;
boolean edit=false;//editing mode on/off
Node cNode,pNode;//current and previous node, for members drawing

void setup() { 
  size(600,600);
  smooth();                   
  nodes=new ArrayList();
  members=new ArrayList();
}

void draw() {
  background(100);
  textAlign(CENTER,CENTER);
  if(edit){
    fill(250,0,100);//things turn magenta in editing mode
  }
  else{
   fill(200); 
  }
  for(int i=0;i<members.size();i++) {//display all members
    Member m=(Member)members.get(i);
    m.display();
  }
  for(int i=0;i<nodes.size();i++) {//display all nodes
    Node n=(Node)nodes.get(i);
    n.display();
  }
  textAlign(LEFT,TOP);
  showTitle();
}

void mousePressed() {
  if(!edit) {//in non-editing mode:
    if(mouseButton==LEFT) {//adding nodes
      nodes.add(new Node(new PVector(mouseX,mouseY))); 
resetCurrent();
    }
    if(mouseButton==RIGHT) {//adding members between the nodes
      if(overNode()) {
        if(pNode!=null)members.add(new Member(cNode,pNode));
      }
      else {
resetCurrent();
      }
    }
  } 
}
void mouseDragged() {
  if(edit) {//in editing mode:
    if(mouseButton==LEFT) {//dragging nodes
      if(overNode()) {
        cNode.pos.x=mouseX;
        cNode.pos.y=mouseY;
      }
    }
  }
  resetCurrent();
}
void keyPressed() {
  if(key==' '){
      resetCurrent();
      edit=!edit;
      }
  if(key=='m')members.clear();//erase all the members
  if(key=='n') {//erase everything
    nodes.clear();
    members.clear();        
resetCurrent();
  }
}

void resetCurrent(){//to avoid unwanted connections   
    cNode=null;
    pNode=null;
    }

boolean overNode() {
  PVector mousePos=new PVector(mouseX,mouseY); 
  boolean isOver=false;      
  for(int i=0;i<nodes.size();i++) {
    Node n=(Node)nodes.get(i);
    if(n.pos.dist(mousePos)<n.size) {
      if(cNode==null)cNode=n;
      else {
        pNode=cNode;
        cNode=n;
      }
      isOver=true;
    }
  }  
  return isOver;
}

void showTitle(){
    fill(200);
    textSize(12);
    text("draw and [in the future] evaluate member trusses",10,10);
    textSize(10);
    text("left click: add node",10,20);
    text("right click on the node: add member",10,30);
    text("space: edit mode-move nodes around",10,40);
    text("'m': delete all members",10,50);
    text("'n': delete everything",10,60);    
    }

class Node {
  PVector pos;
  int size=10;
  Node(PVector _pos) {
    pos=_pos;
  }
  void display() {
      if(cNode==this){
         stroke(250,0,100);
         strokeWeight(3); 
          }
          else{
              stroke(0);
              strokeWeight(1);
              }
      ellipse(pos.x,pos.y,size,size);
  }
}
class Member {
  Node n1,n2;
  float l;
  Member(Node _n1,Node _n2) {
    n1=_n1;
    n2=_n2;
 }
  void display() {
      stroke(0);
      strokeWeight(1);
    line(n1.pos.x,n1.pos.y,n2.pos.x,n2.pos.y);
    l=dist(n1.pos.x,n1.pos.y,n2.pos.x,n2.pos.y);
    PVector mid=PVector.add(n1.pos,n2.pos);
    mid.div(2);
    text(round(l),mid.x,mid.y);
  }
}