#include "testserverframework.h"
#include "testserversnakebite.h"
TestServerFramework::TestServerFramework()
   : ServerFramework(8000)
{
   std::cout << "Constructor called" << std::endl;
}
TestServerFramework::~TestServerFramework()
{
}
bool TestServerFramework::onInitialHandshake( ServerPacket * handshake, ServerPacket * reply )
{
   return true;
}
void TestServerFramework::onClientConnected( Client * _client )
{
   TestClient * client = static_cast<TestClient *>(_client);
   
   
   for(std::vector<TestServerSnakeBite *>::iterator it = snakes.begin(); it != snakes.end(); ++it)
   {
      TestServerSnakeBite * sb = *it;
      sb->sendCreateObject(client);
   }
   
   TestServerSnakeBite * head = new TestServerSnakeBite(this, 5, 5, 0.1, 0, true, client);
   addTestServerSnakeBite(head);
   client->m_snake_head = head;
   for(int i = 0; i < 10; i++)
   {
      head = new TestServerSnakeBite(this, 10+7*i, 10+7*i, 0.1, head, false, client);
      addTestServerSnakeBite(head);
   }
   client->m_snake_tail = head;
}
void TestServerFramework::onClientDisconnected( Client * _client )
{
   TestClient * client = static_cast<TestClient *>(_client);
   
   for(std::vector<TestServerSnakeBite *>::iterator it = snakes.begin(); it != snakes.end();)
   {
      if((*it)->getOwner() == client)
      {
         TestServerSnakeBite * bite = *it;
         it = snakes.erase(it);
         delete bite;
      }
      else
      {
         it++;
      }
   }
}
void TestServerFramework::addTestServerSnakeBite( TestServerSnakeBite * bite )
{
   snakes.push_back(bite);
   
   bite->sendCreateObjectToAll();
   
   bite->sendCreateObject(bite->getOwner());
   bite->sendUpdate(bite->getOwner(), 30, true); 
}
Client * TestServerFramework::createClient( const ipaddress & addr, int port )
{
   return new TestClient(this, addr, port);
}
void TestServerFramework::mainLoop( )
{
   std::cout << "mainLoop()\n";
   while(true)
   {
      
      keepAlive();
      
      for(std::vector<TestServerSnakeBite *>::iterator it = snakes.begin(); it != snakes.end(); ++it)
      {
         TestServerSnakeBite * sb = *it;
         sb->updateMovement();
      }
      
      for(std::map<unsigned int, Client *>::iterator it1 = getAllClients().begin(); it1 != getAllClients().end(); ++it1)
      {
         TestClient * c1 = static_cast<TestClient *>(it1->second);
         for(std::map<unsigned int, Client *>::iterator it2 = getAllClients().begin(); it2 != getAllClients().end(); ++it2)
         {
            TestClient * c2 = static_cast<TestClient *>(it2->second);
            if(c1 == c2 || c2->m_snake_tail->isHead())
               continue;
            if(c1->m_snake_head->dist(*c2->m_snake_tail) < 10.0)
            {
               TestServerSnakeBite * eaten_tail = c2->m_snake_tail;
               
               c2->m_snake_tail = eaten_tail->m_nextbite;
               
               eaten_tail->m_nextbite = c1->m_snake_tail;
               c1->m_snake_tail = eaten_tail;
               eaten_tail->m_owner = c1;
               
               eaten_tail->sendUpdate(c1, 30, true);
               eaten_tail->sendUpdate(c2, 40, true);
               
               eaten_tail->sendUpdateToAll(20, true);
            }
         }
      }
      
      for(std::vector<TestServerSnakeBite *>::iterator it = snakes.begin(); it != snakes.end(); ++it)
      {
         TestServerSnakeBite * sb = *it;
         sb->sendUpdateToAll(10, false);
         if(sb->isHead())
         {
            sb->sendUpdate(sb->getOwner(), 30, true);
         }
      }
      
      psleep(100);
   }
}