/*
 * server/World.cc:
 *
 * Copyright (C) 2000 John Watson, jwatson@tempusmud.com
 * 
 * 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.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 * 
 */

#include "World.h"
#include "Zone.h"
#include "Item.h"
#include "ProtoItem.h"
#include "ProtoChar.h"

#include <vector>

#include <fstream>

World::World( const char * name, const char * alias )
        : Entity( name, alias )
{
 
        vector< class ProtoItem * > tmp_proto_items;

        ifstream ifs( "lib/ents/items.dat", ios::binary | ios::in );

        if ( ! ifs ) {
                cout << " NO item file" << endl;
        }
        else {
                while ( ifs ) {
                        class ProtoItem * proto =  new ProtoItem( ifs );

                        if ( proto->ok == false ) {
                                delete proto;
                                break;
                        }

                        tmp_proto_items.push_back( proto );
                }
        }

        cout << " :: item protos loaded: " << tmp_proto_items.size() << endl;

        _protoItems.setSize( tmp_proto_items.size() );

        for ( int i = 0; i < _protoItems.length; ++i ) {
                _protoItems[i] = tmp_proto_items[i];
        }

        ifs.close();

        vector< class ProtoChar * > tmp_proto_chars;

        ifs.open( "lib/ents/chars.dat", ios::binary | ios::in );

        if ( ! ifs ) {
                cout << " NO char file" << endl;
        }
        else {
                while ( ifs ) {
                        class ProtoChar * proto =  new ProtoChar( ifs );

                        if ( proto->ok == false ) {
                                delete proto;
                                break;
                        }
                        
                        tmp_proto_chars.push_back( proto );
                }
        }

        cout << " :: char protos loaded: " << tmp_proto_chars.size() << endl;

        _protoChars.setSize( tmp_proto_chars.size() );

        for ( int i = 0; i < _protoChars.length; ++i ) {
                _protoChars[i] = tmp_proto_chars[i];
        }

        ifs.close();
}

World::~World() {

}

bool World::addZone( class Zone * zone ) {
        return addContent( zone );
}

bool World::removeZone( class Zone * zone ) {
        return removeContent( zone );
}

class Zone * World::getZone( const char * keyword ) {

        Vector< class Entity * >::const_iterator end = _contents.end();
        for ( Vector< class Entity * >::const_iterator iter = _contents.begin();
              iter != end; ++iter ) {
                if ( ! keyword || (*iter)->isName( keyword ) )
                        return dynamic_cast<Zone*> (*iter);
        }
        
        class Zone * zone = new Zone( keyword, keyword );
        
        if ( zone->loadAllData() == false ) {
                delete zone;
                return 0;
        }
        
        zone->setInitialStates();
        addZone( zone );
        zone->executeCmds( this );

        return zone;
}

class ProtoItem * World::getProtoItem( int vnum ) const {
        const int num_protos = _protoItems.length;
        for ( int i = 0; i < num_protos; ++i ) {
                if ( _protoItems[i]->vnum == vnum )
                        return _protoItems[i];
        }
        
        return 0;
}
class Item * World::createNewItem( int vnum ) const {

        class ProtoItem * proto = getProtoItem( vnum );

        if ( proto ) {
                return new Item( proto );
        }

        return 0;
}
                

class ProtoChar * World::getProtoChar( int vnum ) const {
        const int num_protos = _protoChars.length;
        for ( int i = 0; i < num_protos; ++i ) {
                if ( _protoChars[i]->vnum == vnum )
                        return _protoChars[i];
        }
        
        return 0;
}

class Character * World::createNewChar( int vnum ) const {

        class ProtoChar * proto = getProtoChar( vnum );

        if ( proto ) {
                return new Character( proto );
        }

        return 0;
}
                
