/*
....[@@@..[@@@..............[@.................. MUD++ is a written from
....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and
....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++.
....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing
....[@......[@..[@@@@@..[@@@@@.................. development project.  All 
................................................ contributions are welcome. 
....Copyright(C).1995.Melvin.Smith.............. Enjoy. 
------------------------------------------------------------------------------
Melvin Smith (aka Fusion)         msmith@falcon.mercer.peachnet.edu 
MUD++ development mailing list    mudpp-list@spice.com
------------------------------------------------------------------------------
editarea.cc
*/

#include "string.h"
#include "llist.h"
#include "index.h"
#include "room.h"
#include "indexable.h"
#include "server.h"
#include "area.h"
#include "bit.h"
#include "edit.h"

#include "global.h"


void AreaEditor::command( String & arg )
{
	Area *checkArea;
	Room *room;
	LList<PC> pcIterate;
	LList<Area> areaIterate;
	String str;
	String arg1;
	String arg2;

	arg.startArgs();
	arg1 = arg.getArg();
	arg2 = arg.getArgRest(); // remainder

	if( !arg1 )
	{
		str << "\n\r"
			<< "Name: " << area->getName() << "\n\r"
			<< "Area: " << area->getKey() << "\n\r"
			<< "File: " << area->getFile() << "\n\r"
			<< "Security: " << area->getSecurity() << "\n\r"
			<< "Repop: " << area->getRepopMessg() << "\n\r"
			<< "\n\r";
	}
	else if( arg1 == "reload" )
	{
		// There will probably be a problem with someone reloading
		// an area after an index change but before a save.
		// Clean it up later.

		// Check for players in the area.
		PC *ch;
		bool save = false;

		pcIterate = pcs;
		pcIterate.reset();

		while( ( ch = pcIterate.peek() ) )
		{
			pcIterate.next();

			if( ch->inRoom()->getArea() == area )
			{
				if( ch == pc )
				{
					save = true;
					continue;
				}

				pc->out( "Can't reload area. There are players in the zone.\n\r" );
				return;
			}
		}

		String wasIn;

		if( save )
		{
			wasIn = pc->inRoom()->getKey();

			pc->inRoom()->rmCharInv( pc ); 
		}

		area->reload();

		if( save )
		{
			if( !( room = area->lookupRoom( wasIn ) ) )
			{
				// Add code to handle this without shutdown later. -MS

				pc->out( "Fatal error. The room you were in was not reloaded!\n\r" );
				exit(0);
			}

			room->addCharInv( pc );			
		}

		pc->out( "Area reloaded from disk.\n\r" );

		Area *pArea;

		areaIterate = areas;
		areaIterate.reset();

		while( ( pArea = areaIterate.peek() ) )
		{
			areaIterate.next();
			pArea->hardLink();
		}

		pc->out( "World relinked.\n\r" );
		return;
	}
	else if( arg1.abbrev( "index" ) )
	{
		if( !arg2 )
		{
			pc->out( "Invalid argument.\n\r" );
			return;
		}

		if( ( checkArea = lookupArea( arg2 ) ) )
		{
			if( checkArea != area )
			{
				pc->out( "There is already an area with that index.\n\r" );
				return;
			}
		}

		area->setKey( arg2 );
		arg2 += ".are";
		area->setFile( arg2 );
		pc->out( "Area index key set.\n\r" );
		pc->out( "Filename is now : " );
		pc->out( area->getFile() );
		pc->out( "\n\r" );
		area->setDirtyBit();

		// Now set all objects, npcs, rooms, in the area to the new index scope.

		area->npcIndex.setScope( arg2 ); 
		area->objIndex.setScope( arg2 ); 

		return;
	}
	else if( arg1.abbrev( "name" ) )
	{
		if( !arg2 )
		{
			pc->out( "Invalid argument.\n\r" );
			return;
		}

		area->setName( arg2 );
		pc->out( "Area name set.\n\r" );
		area->setDirtyBit();
		return;
	}
	else if( arg1.abbrev( "save" ) )
	{
		if( !area->getDirtyBit() )
		{
			pc->out( "No modifications since last save.\n\r" );
			return;
		}

		if( !area->getName() )
		{
			pc->out( "This area needs a name key first.\n\r" );
			return;
		}

		if( ( checkArea = lookupArea( area->getKey() ) ) )
		{
			if( checkArea != area )
			{
				pc->out( "There is already an area with that index.\n\r" );
				return;
			}
		}	
		else
		{
			areas.addTop( area );
		}

		area->writeTo();

		pc->out( "Area saved.\n\r" );
		area->rmDirtyBit();
		return;
	}

	pc->out( str );	
}