/*

g++ -o ga-example-004 -Wall -ansi -pedantic -std=c++11 -O3 ga-example-004.cc

./ga-example-004

*/

#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>

#include "ga.hpp"

// We will define a dummy squared block, that we will try to push at
// different positions, in order to see how far it goes. 2*TEST_RADIUS
// is its side length.
#define TEST_RADIUS .25

int main(int argc, char* argv[]) { 
  ga::Blocks blocks;

  blocks.push_back(ga::Block(4,1));           // #0
  blocks.push_back(ga::Block(1.5,.5));        // #1
  blocks.push_back(ga::Block(4,2));           // #2
  blocks.push_back(ga::Block(3,1));           // #3
  blocks.push_back(ga::Block(1,1));           // #4
  blocks.push_back(ga::Block(2*TEST_RADIUS,
			     2*TEST_RADIUS)); // #5 The positions will be tested for that block.

  ga::Setup setup;

  // We push all the blocks, except the test block #5.
  ga::push(setup,blocks,0,1);
  ga::push(setup,blocks,1,5);
  ga::push(setup,blocks,2,3);
  ga::push(setup,blocks,3,3);
  ga::push(setup,blocks,4,2.5);

  // This computes the minimal container length required for this
  // setup.
  double heighest = ga::highest(setup,blocks);

  // This computes a collection of (a,b) pairs, ordered according to
  // a. In pair (a,b), a is some column position, and b some block
  // height. Pair (a,b) means that from column a until the a' of next
  // (a',b') pair, the pushing of the block (#5) will put the block at
  // height b. The last pair (a,b) of the collection has a negative
  // fake b. For this pair, a is the right-most allowed column for a
  // block #5 push.
  ga::Push push;
  ga::try_push(setup,blocks,push,5);
  
  std::ofstream file;
  ga::Position origin(9,15);

  xfig::open("setup-03.fig",file);
  
  // We draw the container
  xfig::draw(file,origin,
  	     blocks,setup);

  // Now, let us mark with a small red circle the positions where
  // block #5 can be pushed. The last marked position is the
  // right-most limit.
  xfig::GC gc;
  gc.colorRed();
  double last_height=0;
  for(auto& push_position : push) {
    double column = push_position.first;
    double height = push_position.second;
    if(height< 0) // right-most limit reached.
      height = last_height;
    last_height = height;
    xfig::circle(file,gc,ga::Position(column,height)+origin,TEST_RADIUS);
  }

  // Let us mark the highest block level.
  gc.colorGreen();
  xfig::line(file,gc,
	     ga::Position(0,heighest)+origin,
	     ga::Position(gaWIDTH,heighest)+origin);

  xfig::close(file);
  
  return 0;
}