// Description:
//   Enemy factory to help create enemy objects.
//
// Copyright (C) 2001 Frank Becker
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation;  either version 2 of the License,  or (at your option) any  later
// version.
//
// This program is distributed in the hope that it will be useful,  but  WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
//
#include <string>

#include <LevelPack.hpp>
#include <EnemyFactory.hpp>
#include <ModelManager.hpp>
#include <LPathManager.hpp>
#include <SimpleEnemy.hpp>

//helper
inline static float strToFloat( const string &str)
{
    return (float)atof( str.c_str());
}

//count siblings of the same type
inline static int countSiblings( TiXmlNode *node, const string & name)
{
    int count = 0;
    while( node)
    {
	count++;
	node = node->NextSibling( name);
    }
    return count;
}

void EnemyFactory::createEnemy( TiXmlNode *enemyNode)
{
    TiXmlNode *node;
    TiXmlElement *elem;
    
    LPathManager &lpm = *LPathManagerS::instance();
    ModelManager &mm = *ModelManagerS::instance();

    LEnemy *enemy = new LEnemy();

    elem = enemyNode->ToElement();
    enemy->spawnTime = strToFloat( *elem->Attribute("spawnTime"));

    node = enemyNode->FirstChild("Model");
    elem = node->ToElement();
    string fullModelName = "models/" + *elem->Attribute("Name");
    enemy->model = mm.getModel( fullModelName);
    
    node = enemyNode->FirstChild("SpawnPoint");
    elem = node->ToElement();
    enemy->spawnPoint.x = strToFloat( *elem->Attribute("x"));
    enemy->spawnPoint.y = strToFloat( *elem->Attribute("y"));
    enemy->spawnPoint.z = strToFloat( *elem->Attribute("z"));
    
    node = enemyNode->FirstChild("Home");
    elem = node->ToElement();
    enemy->home.x = strToFloat( *elem->Attribute("x"));
    enemy->home.y = strToFloat( *elem->Attribute("y"));
    enemy->home.z = strToFloat( *elem->Attribute("z"));

    node = enemyNode->FirstChild("EntryPath");
    elem = node->ToElement();
    enemy->entry = lpm.getPath( *elem->Attribute("Name"));

    node = enemyNode->FirstChild("IdlePath");
    elem = node->ToElement();
    enemy->idle = lpm.getPath( *elem->Attribute("Name"));

    node = enemyNode->FirstChild("AttackPath");
    enemy->numAttackPaths = countSiblings( node, "AttackPath");
    enemy->attack = new LPath*[ enemy->numAttackPaths];
    for( int i=0; i< enemy->numAttackPaths; i++)
    {
	elem = node->ToElement();
	enemy->attack[ i] = lpm.getPath( *elem->Attribute("Name"));
	node = node->NextSibling( "AttackPath");
    }

    node = enemyNode->FirstChild("RetreatPath");
    enemy->numRetreatPaths = countSiblings( node, "RetreatPath");
    enemy->retreat = new LPath*[ enemy->numRetreatPaths];
    for( int i=0; i< enemy->numRetreatPaths; i++)
    {
	elem = node->ToElement();
	enemy->retreat[ i] = lpm.getPath( *elem->Attribute("Name"));
	node = node->NextSibling( "RetreatPath");
    }

    new SimpleEnemy( enemy);
}
