void ComponentIconListBox::addSortedItem( ComponentListItem* pItem )
{
	int size = pItem->getComponent()->getComponentHeight() * 
				pItem->getComponent()->getComponentWidth();

	for ( int i = 0; i < itemCount; i++ )
	{
		LogisticsComponent* pTmp = ((ComponentListItem*)items[i])->getComponent();
		long tmpSize = pTmp->getComponentHeight() * pTmp->getComponentWidth();
		if ( size > tmpSize )
		{
			InsertItem( pItem, i );
			return;
		}
		else if ( size == tmpSize && 
			stricmp( pItem->getComponent()->getName(), pTmp->getName() ) < 0 )
		{
			InsertItem( pItem, i );
			return;
		}
	}

	
	aListBox::AddItem( pItem );
}
void MechLabScreen::removeComponent( long i, long j )
{

	long tmpX, tmpY;
	LogisticsComponent* pComp = pVariant->getCompAtLocation(i, j, tmpX, tmpY );
	if ( pComp )
	{
		if ( !pComp->isAvailable() )
		{
			LogisticsOneButtonDialog::instance()->setText(IDS_MC_UNAVAILABLE_TECH, IDS_DIALOG_OK, IDS_DIALOG_OK);
			LogisticsOneButtonDialog::instance()->begin();
			bErrorDlg = true;
		}
	}
	long tmpHeat = pVariant->getHeat();
	long tmpArmor = pVariant->getArmor();
	pVariant->removeComponent( i, j );

	if ( tmpHeat != pVariant->getHeat() )
	{
		oldHeat = tmpHeat;
		heatTime = .0001f;
	}
	else if ( tmpArmor != pVariant->getArmor() )
	{
		oldArmor = tmpArmor;
		armorTime = .0001f;
	}
	updateDiagram();
			
}
int MechLabScreen::selectFirstDiagramComponent()
{
	if ( !pVariant )
		return -1;
	int count = 0;
	bool bFound = 0;
	componentListBox.SelectItem( -1 );
	for ( int j = 0; j < pVariant->getComponentAreaHeight(); j++ )
	{
		for ( int i = 0; i < pVariant->getComponentAreaWidth(); i++ )
		{
			LogisticsComponent* pComp = pVariant->getCompAtLocation(i, j, selI, selJ );
			if ( pComp )
			{
				count++;
				bFound = true;
				pSelectedComponent = pComp;
				camera.setComponent( pComp->getPictureFileName() );
				break;
			}
		}
		if ( bFound )
			break;
	}

	if ( !bFound )
	{
		selI = -1;
		selJ = -1;
		return -1;
	}

	return count;
}
int32_t LogisticsVariant::init(CSVFile* file, LogisticsChassis* pChassis, int32_t Variant)
{
	bDesignerMech = true;
	int32_t offset = 97 * Variant;
	fileID = Variant;
	gosASSERT(pChassis);
	chassis = pChassis;
	ID = (pChassis->refCount << 16) | pChassis->ID;
	\
	pChassis->refCount++;
	file->readBoolean(21 + offset, 4, bHidden);
	char buffer[256];
	if(NO_ERROR == file->readString(23 + offset, 2, buffer, 256))
	{
		variantName = buffer;
	}
	LogisticsComponent*  pComps[128];
	int32_t xLocs[128];
	int32_t yLocs[128];
	memset(pComps, 0, sizeof(LogisticsComponent*) * 128);
	int32_t componentCount = 0;
	int32_t i, j, k;
	for(i = 26; i < 97; i++)
	{
		int32_t componentID;
		if(NO_ERROR == file->readLong(offset + i, 5, componentID) && componentID != 0xff)
		{
			LogisticsComponent* pComp = LogisticsData::instance->getComponent(componentID);
			if(pComp)
			{
				file->readLong(offset + i, 4, yLocs[componentCount]);
				file->readLong(offset + i, 3, xLocs[componentCount]);
				pComps[componentCount++] = pComp;
			}
		}
	}
	for(j = 4; j > 0; j--)
	{
		for(k = 3; k > 0; k--)
		{
			for(i = 0; i < componentCount; i++)
			{
				LogisticsComponent*
				pComponent = pComps[i];
				if(pComponent && pComponent->getComponentWidth() == k
						&& pComponent->getComponentHeight() == j)
				{
					if(!addComponent(pComps[i]->getID(), xLocs[i], yLocs[i]))
					{
						char errorString[256];
						sprintf(errorString, "Couldn't add component with id %ld",
								pComponent->getID());
					}
				}
			}
		}
	}
	return 0;
}
int MechLabScreen::selectFirstLBComponent()
{
	selI = selJ = -1;
	pSelectedComponent = NULL;
	int index =  componentListBox.selectFirstAvailableComponent();
	if ( index != -1 )
	{
		LogisticsComponent* pComp = componentListBox.getComponent( );
		camera.setComponent( pComp->getPictureFileName() );
	}
	return index;
}
const LogisticsChassis::ComponentInfo* LogisticsVariant::getComponentAtLocation(int32_t x, int32_t y) const
{
	if(x == -1 && y == -1)
		return nullptr;
	for(size_t i = 0; i < componentCount; ++i)
	{
		LogisticsComponent* pComponent = components[i].component;
		for(size_t j = 0; j < pComponent->getComponentHeight(); ++j)
		{
			for(size_t k = 0; k < pComponent->getComponentWidth(); ++k)
			{
				if(components[i].xCoord + k == x
						&& components[i].yCoord + j == y)
				{
					return &components[i];
				}
			}
		}
	}
	return nullptr;
}
const LogisticsChassis::ComponentInfo* LogisticsVariant::getComponentAtLocation( long x, long y ) const
{
	if ( x == -1 && y == -1 )
		return NULL;

	for ( int i = 0; i < componentCount; ++i )
	{
		LogisticsComponent* pComponent = components[i].component;

		for ( int j = 0; j < pComponent->getComponentHeight(); ++j )
		{
			for ( int k = 0; k < pComponent->getComponentWidth(); ++k )
			{
				if ( components[i].xCoord + k == x
					 && components[i].yCoord + j == y )
				{
					return &components[i];
				}
			}
		}
	}

	return NULL;
}
bool LogisticsVariant::addComponent( int idFromFitFile, long& x, long& y )
{
	LogisticsComponent*
		pComponent = LogisticsData::instance->getComponent( idFromFitFile );


	if ( !pComponent )
	{
	//	Assert( 0, idFromFitFile, "couldn't find the component in the fit file\n" );
		delete pComponent;
		return false;
	}

	if ( pComponent->getType() == COMPONENT_FORM_JUMPJET )
	{
		components[componentCount].location = LEGS;
		x = y = -2;
	}

	else if ( pComponent->getType() == COMPONENT_FORM_ECM || pComponent->getType() == COMPONENT_FORM_SENSOR )
	{
		components[componentCount].location = HEAD;
		x = y = -3;
	}

	else
	{


		// need to see if this thing will fit
		long componentWidth = pComponent->getComponentWidth();
		long componentHeight = pComponent->getComponentHeight();

		if ( x == -1 && y == -1 )
		{
			for ( int j = 0; j < chassis->componentAreaHeight && x == -1; j++ )
			{
				for ( int i = 0; i < chassis->componentAreaWidth && x == -1; i++ )
				{
					bool bAdd = true;
					for ( int l = 0; l < componentHeight; ++l )
					{
						for ( int k =0; k < componentWidth; ++k )
						{

 							if ( getComponentAtLocation( i +k, j + l ) 
								|| ( i + k >= chassis->componentAreaWidth )
								|| ( j +l >= chassis->componentAreaHeight ) )
							{
								bAdd = false;
								break;
								break;
							}
						}
					}

					if ( bAdd )
					{
						x = i;
						y = j;
			
					}
				}
			}
		}

		if ( x == -1 && y == -1 )
			return 0;

		if ( x > -1 )
		{
			for ( int i =0; i < componentWidth; ++i )
			{
				for ( int j = 0; j < componentHeight; ++j )
				{
 					if ( getComponentAtLocation( x +i, y + j ) )
					{
						char errorString[1024];
						sprintf( errorString, "couldn't add component %s to variant %s because another object was in the specified location", 
							pComponent->getName(), this->getName().Data() );
		//				Assert( 0, 0, errorString );
						return false; 
					}
				}
			}
		}

		components[componentCount].location = CHEST;
	}

	components[componentCount].component = pComponent;
	components[componentCount].xCoord = x;
	components[componentCount].yCoord = y;
	componentCount++;
	return true;
}
void MechLabScreen::updateDiagramInput()
{
	long mouseX = userInput->getMouseX();
	long mouseY = userInput->getMouseY();


	if ( rects[13].pointInside( mouseX, mouseY ) )
	{
		long x, y, x2, y2;
		getMouseDiagramCoords( x, y );	
		
		if ( x != -2 )
		{
			// now offset by size of the component
			if ( pDragComponent )
			{
				long screenX, screenY;
				diagramToScreen( x, y, screenX, screenY );

				x -= pDragComponent->getComponentWidth()/2;
				y -= pDragComponent->getComponentHeight()/2;

				if ( mouseX - screenX > LogisticsComponent::XICON_FACTOR/2
					&& pDragComponent->getComponentWidth()/2)
				{
					x += 1;
				}	
			}

			if ( x < 0 )
				x = 0;

			if ( x >= pVariant->getComponentAreaWidth() - 1 ) 
				x = pVariant->getComponentAreaWidth() - 1;

			if ( y < 0 )
				y = 0;

			if ( y >= pVariant->getComponentAreaHeight() - 1 )
				y = pVariant->getComponentAreaHeight() - 1;

			
			if ( pDragComponent )
			{
				x2 = x + pDragComponent->getComponentWidth();
				y2 = y + pDragComponent->getComponentHeight();	

				if ( x2 > pVariant->getComponentAreaWidth() )
				{
					x = pVariant->getComponentAreaWidth() - pDragComponent->getComponentWidth();
					x2 = pVariant->getComponentAreaWidth();
				}

				if ( y2 > pVariant->getComponentAreaHeight() )
				{
					y = pVariant->getComponentAreaHeight() - pDragComponent->getComponentHeight();
					y2 = pVariant->getComponentAreaHeight();
				}
			}
			else
			{
				x2 = x + 1;
				y2 = y + 1;
			}
		
			long tmpX, tmpY;

			diagramToScreen( x, y, tmpX, tmpY );			

			// update outline rect
			if ( selRect )
				selRect->moveTo( tmpX, tmpY );			


			// highlight text if appropriate
			LogisticsComponent* pComp = pVariant->getCompAtLocation(x, y, tmpX, tmpY );
			if ( pComp )
			{
				long compX, compY, compX2, compY2;
				diagramToScreen( tmpX, tmpY, compX, compY );
				diagramToScreen( tmpX + pComp->getComponentWidth(), tmpY + pComp->getComponentHeight(), compX2, compY2 );
				if ( (compX <= userInput->getMouseX() && compX2 >= userInput->getMouseX()
					&& compY <= userInput->getMouseY() && compY2 >= userInput->getMouseY())
					|| tmpX == -2 )
				{
					::helpTextID = IDS_HELP_COMP0 + pComp->getID();
				}
			}
		}
		else if ( selRect )
		{
			selRect->moveTo( rects[6].left() + rects[6].width()/2 - selRect->width()/2,
							rects[6].top() + rects[6].height()/2 - selRect->height()/2);
		}
		// check for jump jet hot text
		if ( x == -2 && y == -2 )
		{
			long tmpX, tmpY;
			LogisticsComponent* pComp = pVariant->getCompAtLocation(x, y, tmpX, tmpY );
			if ( pComp )
			{
				long compX, compY, compX2, compY2;
				diagramToScreen( tmpX, tmpY, compX, compY );
				diagramToScreen( tmpX + pComp->getComponentWidth(), tmpY + pComp->getComponentHeight(), compX2, compY2 );
				if ( (compX <= userInput->getMouseX() && compX2 >= userInput->getMouseX()
					&& compY <= userInput->getMouseY() && compY2 >= userInput->getMouseY())
					|| tmpX == -2 )
				{
					::helpTextID = IDS_HELP_COMP0 + pComp->getID();
				}
			}
		}
		

		if ( pDragComponent )
		{
			if (NO_ERR == pVariant->canAddComponent( pDragComponent, x, y )
				&& x != -1 && y != -1 )
			{
				selRect->setColor( 0xffffffff );
			}
			else
				selRect->setColor( 0xffff0000 );			
		}			
		else if ( userInput->isLeftDrag() )
		{
			long i, j;
			getMouseDiagramCoords( i, j );

			if ( i != -1 && j != -1 )
			{
				LogisticsComponent* pComp = pVariant->getCompAtLocation(i, j, selI, selJ );
				if ( pComp && pComp == pSelectedComponent )
				{
					if ( canRemoveComponent( pComp ) )
					{
						componentListBox.SelectItem( -1 );
						beginDrag( pComp );
						bDragLeft = true;
						removeComponent( i, j );
						setComponent( pComp );
						updateDiagram();
					}
					else
						soundSystem->playDigitalSample( LOG_WRONGBUTTON );
				}
				else
					pSelectedComponent = 0;
			}

		}
		else if ( userInput->isLeftDoubleClick() )
		{
			long tmpI, tmpJ;
			getMouseDiagramCoords( tmpI, tmpJ );

			if ( tmpI != -1 && tmpJ != -1 )
			{
				selI = tmpI;
				selJ = tmpJ;
				LogisticsComponent* pComp = pVariant->getCompAtLocation(tmpI, tmpJ, selI, selJ );
				if ( pComp )
				{
					if ( canRemoveComponent( pComp ) )
					{
						removeComponent( selI, selJ );
						componentListBox.SelectItem( -1 );
						if ( -1 == selectFirstDiagramComponent() )
							selectFirstLBComponent();				
					}
					else
						soundSystem->playDigitalSample( LOG_WRONGBUTTON );
				}
			}
		
		}
		else if ( userInput->isLeftClick() )
		{
			long tmpI, tmpJ;
			getMouseDiagramCoords( tmpI, tmpJ );

			if ( tmpI != -1 && tmpJ != -1 )
			{
				selI = tmpI;
				selJ = tmpJ;
				LogisticsComponent* pComp = pVariant->getCompAtLocation(tmpI, tmpJ, selI, selJ );
				if ( pComp )
				{
					pSelectedComponent = pComp;
					setComponent( pComp );
					soundSystem->playDigitalSample( LOG_SELECT );
					componentListBox.SelectItem( -1 );
				}
			}
		}		
	}

	if ( userInput->leftMouseReleased() && pDragComponent )
			endDrag();


}
void MechLabScreen::updateDiagram()
{
	if ( !pVariant || status != RUNNING )
		return;

	int width = pVariant->getComponentAreaWidth();
	long minX = rects[7 + 6-width].left();
	long maxY = rects[7].bottom();

	long minY = maxY - pVariant->getComponentAreaHeight() * LogisticsComponent::YICON_FACTOR;

	long IDArray[128];
	long xLocs[128];
	long yLocs[128];
	componentCount = 128;


	pVariant->getComponentsWithLocation(  componentCount, IDArray, xLocs, yLocs );
	for ( int i = 0; i < componentCount; i++ )
	{
		LogisticsComponent* pComponent = LogisticsData::instance->getComponent( IDArray[i] );

		long xLoc = minX + xLocs[i] * LogisticsComponent::XICON_FACTOR;
		long yLoc = minY + yLocs[i] * LogisticsComponent::YICON_FACTOR;

		if ( pComponent->getType() == COMPONENT_FORM_JUMPJET )
		{
			xLoc =	rects[6].left();
			yLoc = rects[6].top();
			 
		}

		int sizeX = pComponent->getComponentWidth();
		int sizeY = pComponent->getComponentHeight();
	

		const char* pFile = pComponent->getIconFileName();

		FullPathFileName path;
		path.init( artPath, pFile, "tga" );

		componentIcons[i].setTexture( path );
		componentIcons[i].resize( sizeX * LogisticsComponent::XICON_FACTOR, sizeY * LogisticsComponent::YICON_FACTOR );
		componentIcons[i].setUVs( 0.f, 0.f, sizeX * 48.f, sizeY * 32.f );
		componentIcons[i].moveTo( xLoc, yLoc );
		componentIcons[i].setColor( 0xffffffff );
	}

	// update heat
	updateHeatMeter();
	updateArmorMeter();

	// update cost
	float newCost = pVariant->getCost();

	// figure out change
	float costChange = newCost - originalCost;

	if ( costChange != oldCBillsAmount )
	{
		previousAmount = oldCBillsAmount - costChange;
		curCount = .00001f;
		oldCBillsAmount = costChange;
		if ( previousAmount < 0 )
			soundSystem->playDigitalSample( WINDOW_OPEN );
		else
			soundSystem->playDigitalSample( WINDOW_CLOSE );
	}




}