/** SGX

The   sss    gggg x   x   
     s      g      x x    Engine
      sss   g  gg   x
         s  g   g  x x          Copyright 1995-2009.
     ssss    gggg x   x         Steven Goodwin. All Rights Reserved.
    
This version has been released under the GNU Public License v2.0.

Please see the license files for details.

File: sgx/src/sgx/core/gamecode/layer_engine.cpp

*/

#include "sgx/core/core.hpp"

//
// The engine
//
CSGXLayerEngine::CSGXLayerEngine() :
	m_bReverseRender(FALSE) {
}


sgxLayer *	
CSGXLayerEngine::getLayer(tDepth depth) {
	sgxVector<sgxLayer *>::const_iterator cit = m_LayerList.begin();
	for(;cit != m_LayerList.end();++cit) {
		if (depth == (*cit)->m_Depth) {
			return *cit;
		}
	}
	return NULL;
}

sgxLayer *	
CSGXLayerEngine::createLayer(tDepth depth) {
	sgxLayer *pLayer = getLayer(depth);

	if (!pLayer) {
		pLayer = new sgxLayer(depth);
		reorderLayer(pLayer, depth);
	}
	return pLayer;
}


tBOOL		
CSGXLayerEngine::addObject(const CGameHandler *pObj, tDepth depth) {
	sgxLayer *pLayer = createLayer(depth);
	return pLayer->addObject(pObj);
}


void		
CSGXLayerEngine::removeObject(const CGameHandler *pObj) {
	sgxVector<sgxLayer *>::const_iterator cit = m_LayerList.begin();
	for(;cit != m_LayerList.end();++cit) {
		(*cit)->removeObject(pObj);
	}
}

void		
CSGXLayerEngine::removeLayer(sgxLayer *pLayer) {
	sgxVector<sgxLayer *>::iterator it = find(m_LayerList.begin(), m_LayerList.end(), pLayer);
	if (it != m_LayerList.end()) {
		m_LayerList.erase(it);
	}
}



void		
CSGXLayerEngine::reorderObject(const CGameHandler *pObject, tDepth depth) {
	removeObject(pObject);
	addObject(pObject, depth);
}


void		
CSGXLayerEngine::reorderLayer(sgxLayer *pLayer, tDepth depth) {
	removeLayer(pLayer);

	if (m_LayerList.size() == 0) {
		m_LayerList.push_back(pLayer);
		return;
	}

	sgxVector<sgxLayer *>::iterator it = m_LayerList.begin();
	sgxLayer *pPreviousLayer = NULL;
	for(;it != m_LayerList.end();++it) {
		pPreviousLayer = *it;
		
		if (depth < (*it)->m_Depth) {
			break;
		}
	}

	m_LayerList.insert(it, pLayer);	// insert adds 'before' the 'it' object
}


void 
CSGXLayerEngine::draw() const
{
	if (m_bReverseRender) {
		sgxVector<sgxLayer *>::const_reverse_iterator it = m_LayerList.rbegin();
		for(;it != m_LayerList.rend();++it) {
			(*it)->draw();
		}
	} else {	// normal
		sgxVector<sgxLayer *>::const_iterator cit = m_LayerList.begin();
		for(;cit != m_LayerList.end();++cit) {
			(*cit)->draw();
		}
	}
}

//
// The layers
//
sgxLayer::sgxLayer(CSGXLayerEngine::tDepth depth) {
	m_Depth = depth;
}

tBOOL
sgxLayer::addObject(const CGameHandler *pObj) {
	m_ObjectList.push_back(pObj);
	return TRUE;
}

void
sgxLayer::removeObject(const CGameHandler *pObj) {
	sgxVector<const CGameHandler *>::iterator it = find(m_ObjectList.begin(), m_ObjectList.end(), pObj);
	if (it != m_ObjectList.end()) {
		m_ObjectList.erase(it);
	}
}


void 
sgxLayer::draw() const
{
	sgxVector<const CGameHandler *>::const_iterator cit = m_ObjectList.begin();
	for(;cit != m_ObjectList.end();++cit) {
		(*cit)->draw();
	}
}
