#include "timer.h"

#include <Atlas/Message/Element.h>

#include <iostream>
#include <cassert>

using Atlas::Message::Element;
using Atlas::Message::ListType;
using Atlas::Message::MapType;

class NPC
{
public:
  NPC() : id("123") {x=y=z = vx=vy=vz = 0.0;}
  Element move(const Element &op);
  std::string getId() {return id;}
private:
  std::string id;
  double x,y,z;
  double vx,vy,vz;
};

Element NPC::move(const Element &op)
{
  ListType::iterator new_vel_i = ((Element&)op).asMap()["args"].asList().
    front().asMap()["velocity"].asList().begin();
  vx = (*new_vel_i).asFloat();
  new_vel_i++; vy = (*new_vel_i).asFloat();
  new_vel_i++; vz = (*new_vel_i).asFloat();

  x += vx;
  y += vy;
  z += vz;

  //human:
  MapType human;
  human["id"] = getId();
  ListType pos;
  pos.push_back(x);
  pos.push_back(y);
  pos.push_back(z);
  human["pos"] = pos;
  ListType vel;
  vel.push_back(vx);
  vel.push_back(vy);
  vel.push_back(vz);
  human["velocity"] = vel;
  
  //move:
  MapType move;
  move["objtype"] = Element("op");
  ListType move_parents(1, Element("move"));
  move["parents"] = move_parents;
  ListType move_args(1, human);
  move["args"] = move_args;
  
  //sight:
  MapType sight;
  sight["objtype"] = Element("op");
  ListType sight_parents(1, Element("sight"));
  sight["parents"] = sight_parents;
  sight["from"] = getId();
  ListType sight_args(1, move);
  sight["args"] = sight_args;

  return sight;
}

int main(int argc, char** argv)
{
  double i;
  Element bar(42);
  std::cout<<sizeof(bar)<<std::endl;
  TIME_ON;
  for(i=0; i<100000.0; i+=1.0) {
    //human:
    MapType human;
    human["objtype"] = Element("object");
    ListType human_parents(1, Element("human"));
    human["parents"] = human_parents;
    ListType pos;
    pos.push_back(i);
    pos.push_back(i-1.0);
    pos.push_back(i+1.0);
    human["pos"] = pos;
    ListType vel;
    vel.push_back(i);
    vel.push_back(i-1.0);
    vel.push_back(i+1.0);
    human["velocity"] = vel;

    //move:
    MapType move;
    move["objtype"] = Element("op");
    ListType move_parents(1, Element("move"));
    move["parents"] = move_parents;
    ListType move_args(1, human);
    move["args"] = move_args;

    //sight:
    MapType sight;
    sight["objtype"] = Element("op");
    ListType sight_parents(1, Element("sight"));
    sight["parents"] = sight_parents;
    sight["from"] = Element("123");
    ListType sight_args(1, move);
    sight["args"] = sight_args;

#if 0
    cout<<"----------------------------------------------------------------------"<<endl;
    cout<<"vel0:"<<sight["args"].asList().front().asMap()["args"].asList().front().asMap()["velocity"].asList().front().asFloat()<<endl;

    pos.front() = -i;
    cout<<"vel1:"<<sight["args"].asList().front().asMap()["args"].asList().front().asMap()["velocity"].asList().front().asFloat()<<endl;

    sight["args"].asList().front().asMap()["args"].asList().front().asMap()["velocity"].asList().front() = 2*i;
    cout<<"vel2:"<<sight["args"].asList().front().asMap()["args"].asList().front().asMap()["velocity"].asList().front().asFloat()<<endl;
    
    human["velocity"].asList().front() = -2*i;
    cout<<"vel3:"<<sight["args"].asList().front().asMap()["args"].asList().front().asMap()["velocity"].asList().front().asFloat()<<endl;
#endif
    
  }
  TIME_OFF("Plain creating of sight operation");


  NPC npc1;
  double x = 0., y = 0., z = 0.;
  TIME_ON;
  for(i=0; i<100000.0; i+=1.0) {
    //human:
    MapType human;
    human["id"] = npc1.getId();
    ListType vel;
    vel.push_back(i);
    vel.push_back(i-1.0);
    vel.push_back(i+1.0);
    human["velocity"] = vel;

    //move:
    MapType move;
    move["objtype"] = Element("op");
    ListType move_parents(1, Element("move"));
    move["parents"] = move_parents;
    ListType move_args(1, human);
    move["args"] = move_args;

    Element res_sight = npc1.move(move);
    ListType::iterator new_pos_i = res_sight.asMap()["args"].asList().
      front().asMap()["args"].asList().
      front().asMap()["pos"].asList().begin();
    x = (*new_pos_i).asFloat();
    new_pos_i++; y = (*new_pos_i).asFloat();
    new_pos_i++; z = (*new_pos_i).asFloat();
  }
  TIME_OFF("NPC movements");
  std::cout<<"Resulting position: ("<<x<<","<<y<<","<<z<<")"<<std::endl;

  return 0;
}


syntax highlighted by Code2HTML, v. 0.9.1