/**
 **	File ......... ItemFactory.cpp
 **	Published ....  2004-05-15
 **	Author ....... grymse@alhem.net
**/
/*
Copyright (C) 2004  Anders Hedstrom

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 <stdio.h>
#include "SmallHandler.h"
#include "SmallSocket.h"
#include "ItemFactory.h"




ItemFactory::ItemFactory(SmallHandler& h) : m_handler(h)
{
}


ItemFactory::~ItemFactory()
{
	for (std::map<int, std::map<int, item_v> >::iterator it = m_items.begin(); it != m_items.end(); it++)
	{
		std::map<int, item_v>& ref = (*it).second;
		for (std::map<int, item_v>::iterator it = ref.begin(); it != ref.end(); it++)
		{
			item_v& ref = (*it).second;
			for (item_v::iterator it = ref.begin(); it != ref.end(); it++)
			{
				ITEM *i = *it;
				delete i;
			}
		}
	}
}


ITEM *ItemFactory::CreateRandomItem()
{
	switch (random() % 20)
	{
	case 0:
		return CreateGold( random() % 100 + 100 );
	case 1:
		return new ITEM("a sword","swords","right hand");
	case 2:
		return new ITEM("a dagger","daggers","right hand");
	case 3:
		return new ITEM("a shield","shields","wrong hand");
	case 4:
		return new ITEM("a shoulder cap","shoulder caps","left shoulder");
	case 5:
		return new ITEM("a shoulder cap","shoulder caps","right shoulder");
	case 6:
		return new ITEM("a helmet","helmets","head");
	default:
		return new ITEM("a bucket of spam","buckets of spam","",0,0,1);
	}
	return NULL;
}


ITEM *ItemFactory::CreateGold(long amount)
{
	return new ITEM("a gold coin","gold coins","",0,0,amount);
}


void ItemFactory::Spawn()
{
	int x;
	int y;
	std::string loc;

	m_handler.GetWorld().GetRandomLocation(x,y,loc);

	ITEM *p = CreateRandomItem();
	{
		std::string str = "Suddenly, " + p -> GetDescription() + " appears\n";
		Handler().Event(x,y,str);
	}
	Merge(m_items[x][y],p);
}


void ItemFactory::ShowNamesAt(SmallSocket *p,int x,int y,const std::string& prefix)
{
	item_v& ref = m_items[x][y];
	for (item_v::iterator it = ref.begin(); it != ref.end(); it++)
	{
		ITEM *i = *it;
		p -> Send("  " + prefix + i -> GetDescription() + "\n");
	}
}


ITEM::ITEM(const std::string& n,const std::string& p,const std::string& w) 
:m_vecno(0)
,m_wield_position(w),m_physical(20),m_magical(20),m_amount(1) 
{
	std::string cols[10]; // nrgybmcw
	for (size_t i = 0; i < 10; i++)
	{
		int nr = random() % 8;
		if (!nr)
		{
			nr = random() % 15 + 1;
		}
		cols[i] = "&";
		cols[i] += "nrgybmcwRGYBMCWL"[nr];
	}
	size_t col = 0;
	for (size_t i = 0; i < n.size(); i++)
	{
		if (n[i] == ' ')
		{
			m_name += " ";
			m_name += cols[col++];
		}
		else
		{
			m_name += n.substr(i,1); //n[i];
		}
	}
	col = 0;
	m_plural += cols[col++];
	for (size_t i = 0; i < p.size(); i++)
	{
		if (p[i] == ' ')
		{
			m_plural += " ";
			m_plural += cols[col++];
		}
		else
		{
			m_plural += p.substr(i,1); //p[i];
		}
	}
	if (!random() % 100)
	{
		m_physical += random() % 80 + 1;
		if (!random() % 100)
		{
			m_magical += random() % 80 + 1;
		}
	}
	m_name += "&n";
	m_plural += "&n";
}


ITEM::ITEM(const std::string& n,const std::string& p,const std::string& w,short ph,short ma,long am) 
:m_vecno(0)
,m_name(n)
,m_plural(p)
,m_wield_position(w),m_physical(ph),m_magical(ma),m_amount(am)
{
}


size_t ItemFactory::NumberOfItems()
{
	size_t q = 0;
	for (std::map<int, std::map<int, item_v> >::iterator it = m_items.begin(); it != m_items.end(); it++)
	{
		std::map<int, item_v>& ref = (*it).second;
		for (std::map<int, item_v>::iterator it = ref.begin(); it != ref.end(); it++)
		{
			item_v& ref = (*it).second;
			q += ref.size();
		}
	}
	return q;
}


void ItemFactory::Merge(item_v& ref,ITEM *p)
{
	size_t max = 0;
	for (item_v::iterator it = ref.begin(); it != ref.end(); it++)
	{
		ITEM *i = *it;
		max = i -> m_vecno > max ? i -> m_vecno : max;
	}
	for (item_v::iterator it = ref.begin(); it != ref.end(); it++)
	{
		ITEM *i = *it;
		std::string iname = i -> m_name;
		std::string iplural = i -> m_plural;
		if (iname == p -> m_name &&
		    iplural == p -> m_plural &&
		    i -> m_wield_position == p -> m_wield_position &&
		    i -> m_physical == p -> m_physical &&
		    i -> m_magical == p -> m_magical)
		{
			i -> m_amount += p -> m_amount;
			delete p;
			return;
		}
	}
	p -> m_vecno = max + 1;
	ref.push_back(p);
}