int
main(int argc, char **argv)
{
  DEBUG_STACK_FRAME;
  if (argc != 2)
  {
    std::cout << "Usage: " << argv[0] << " <iterations>" << std::endl;
    exit(__LINE__);
  }
  int iterations = atoi(argv[1]);
  if (iterations <= 0)
  {
    std::cout << "Iterations must be a positive integer, not " << argv[1]
              << std::endl;
    exit(__LINE__);
  }

  std::cout << "Using ~" << sizeof(reqTemplate) << " byte requests" 
           << std::endl;
  std::cout << "Using ~" << sizeof(respTemplate) << " byte responses" 
           << std::endl;

  // Set up Alice's environment
  osc::StateHandler aliceSh(8192,64,8192,2);
  osc::Stack aliceStack(aliceSh);
  aliceStack.addCompressor(new osc::DeflateCompressor(aliceSh));

  // Set up Bob's environment
  osc::StateHandler bobSh(8192,64,8192,2);
  osc::Stack bobStack(bobSh);
  bobStack.addCompressor(new osc::DeflateCompressor(bobSh));

  osc::SigcompMessage *sm;
  osc::StateChanges *sc;

  osc::byte_t output[8192];
  size_t outputSize;

  int compartmentId = 0x12345678;

  osc::byte_t input[8192];
  size_t inputSize;

  char * string1 = genString(0);
  char * string2 = genString(1);
  int cseq = rand();

  for (int i = 0; i < iterations; i++)
  {
    string1 = genString(0);
    cseq++;

    if (!(i%10))
    {
      compartmentId++;
      string2 = genString(1);
    }

    if (i%2)
    {
      inputSize = snprintf((char *)input, sizeof(input), reqTemplate,
                           string1, string2, cseq,
                           rand(), rand(), rand(), rand());
      sm = aliceStack.compressMessage(
             input, inputSize, compartmentId);

      outputSize = bobStack.uncompressMessage(
                     sm->getDatagramMessage(), sm->getDatagramLength(),
                     output, sizeof(output), sc);

      assert(!bobStack.getNack());
      bobStack.provideCompartmentId(sc, compartmentId);
    }
    else
    {
      inputSize = snprintf((char *)input, sizeof(input), respTemplate,
                           string1, string2, cseq);
      sm = bobStack.compressMessage(
             input, inputSize, compartmentId);

      outputSize = aliceStack.uncompressMessage(
                     sm->getDatagramMessage(), sm->getDatagramLength(),
                     output, sizeof(output), sc);

      assert(!aliceStack.getNack());
      aliceStack.provideCompartmentId(sc, compartmentId);
    }

  }

  return 0;
}
vector< vector<float> > LSysDecoder::grow(cv::Point3f start, int depth, glm::vec3 dir)
{
    vector< vector<float> > finalNodes;
    vector<float> arr;
    string rule = genString(depth);

    arr.push_back(start.x);
    arr.push_back(start.y);
    arr.push_back(start.z);

    int cnt = 0;
    float theta = 25.0f;

    stack<cv::Point3f> st;
    stack<int> aux;

    for (int i = 0; i < rule.size(); ++i)
    {
        if(rule[i] != ']')
        {
            if(rule[i] == '[')
            {
                st.push(cv::Point3f(arr[arr.size()-3], arr[arr.size()-2], arr[arr.size()-1]));
                aux.push(cnt);
            }

            else if(rule[i] == 'F')
            {
//                start.x -= (cnt*(random()%10 + 1));
//                start.y -= len;
//                start.z -= (cnt*(random()%10 + 1));
                int del = (random()%10);

                start.x += len*dir.x;
                start.y += len*dir.y;
                start.z += (len*dir.z - del);

                arr.push_back(start.x);
                arr.push_back(start.y);
                arr.push_back(start.z);

                arr.push_back(start.x);
                arr.push_back(start.y);
                arr.push_back(start.z);
            }

            else if(rule[i] == '+')
            {
                glm::vec3 tvec = glm::normalize(glm::cross(dir, glm::vec3(dir.x-1, 0.0f, 0.0f)));
                glm::mat4 rot = glm::rotate(glm::mat4(1.0f),glm::radians(theta),tvec);
                dir = glm::mat3(rot) * dir;
            }
//                cnt ++;
            else if(rule[i] == '-')
            {
                glm::vec3 tvec = glm::normalize(glm::cross(dir, glm::vec3(dir.x-1, 0.0f, 0.0f)));
                glm::mat4 rot = glm::rotate(glm::mat4(1.0f),glm::radians(-theta),tvec);
                dir = glm::mat3(rot) * dir;
            }
//                cnt --;
        }
        else
        {
            start = st.top();
            cnt = aux.top();

            arr.push_back(arr[arr.size()-3]);
            arr.push_back(arr[arr.size()-3]+1);
            arr.push_back(arr[arr.size()-3]);
            finalNodes.push_back(arr);
            arr.clear();

            arr.push_back(start.x);
            arr.push_back(start.y);
            arr.push_back(start.z);

            st.pop();
            aux.pop();
        }
    }

    return finalNodes;
}