norefresh
set antialias 1

//This dbnlet contains a curve defined by the moving lines in 
//assignment 3a.  This curve moves to follow the mouse as it is dragged.
//As in assignment 3a, this structure is supported, except this time 
//the structure is taken from assignment 4b.

//The dots at each end of the line are taken from assignment 3b, and the 
//block at the bottom is from assigment 1a.  

//I experimented with some blocks on the side from assignment 4b,
//but they didn't seem to fit.

//When not manipulated with the mouse, these elements come together
//to form a sort of tower structure: wide at the base and narrow at the top. 

//When moved with the mouse, the line looks somewhat like the sail from a boat.
//It's as if the dots at each end are holding it in place as it blows in the wind.



set a 2
set r1 20
set r2 20
set x1 50
set dx 0
set idx dx
set x2 67

//float point pow() lookup table
set <array 10> 1000
set <array 11> 1072
set <array 12> 1149
set <array 13> 1231
set <array 14> 1320
set <array 15> 1414
set <array 16> 1516
set <array 17> 1624
set <array 18> 1741
set <array 19> 1866
set <array 20> 2000

number nudge x g
{
   //give the illusion of a floating point pow function
   //this function assumes a == 2.
   //essentially a lookup table
   set v (1000*x/(<array (g+10)>))
   value v
}

number pow x y
{
   //x is *10, but nudge assumes it is 2.0 for now
   //y is *10 ie pow 2 15 is 2 ** 1.5
   set val 1
   repeat c 0 (y/10)
   {
      set val (val*x/10)
   }
   //line 0 0 x val
   set val <nudge val (10-(y%10))>
   value val
}

//this is not very precise at all...
number root x y
{
   set c 10
   set val <pow c (y*10)>
   //is there a while loop in dbn?
   repeat d 0 60
   {
      smaller? val x
      {
         set c (c+1)
         set val <pow c (y*10)>
      }
   }
   value c
}

command drawHolder
{
   field 49 20 61 22 50
}

command drawBlock
{
   field 40 0 50 10 20
  // put little blocks on the side from assignment 4b
  // repeat i 2 7
  // {
  //    field 0 (i*10) 3 (i*10+8) 20
  //    field 5 (i*10) 13 (i*10+8) 20
  // }
  // field 5 30 13 38 100
  // field 5 60 13 68 0
}

command drawLines
{
   paper 0
   pen 100

   set x2 60
   set y2 3

   repeat c 0 60
   {
      set y1 (a + <pow r1 c>)
      //set y2 (a + <pow r2 c>)
      set x1 (60 + dx*c/10)
      //set x1 (dx*c/10)
      line x1 y1 x2 y2
      set x2 x1
      set y2 y1
   }
   field 0 69 100 100 0
}

command drawDots
{
   field (62 + dx*23/10) 5 (64 + dx*23/10) 7 50
   field (56 + dx*395/100) 60 (58 +dx*395/100) 62 100
}

forever
{
   same? <mouse 3> 100
   {
      set dx ((<mouse 1> - 50) / 4)
      set r1 <root (<mouse 2> - 2) 4>
   }
   notsame? <mouse 3> 100
   {
      notsame? dx idx
      {
         smaller? dx idx
         {
            set dx (dx + 1)
         }
      }
      //check this twice to simulate "<" (rather than <=)
      notsame? dx idx
      {
         notsmaller? dx idx
         {
            set dx (dx -1)
         }
      }
      notsame? r1 20
      {
         smaller? r1 20
         {
            set r1 (r1 + 1)
         }
         notsmaller? r1 20
         {
            set r1 (r1 -1)
         }
      }
   }
   refresh
   drawLines
   drawBlock
   drawHolder
   drawDots
}