/*
* Hub.cs
* Authors: Bradley R. Blankenship
* Copyright (c) 2007-2008 Cornell University
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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework;
namespace ColonySim.Structures
{
///
/// Represents a Hub in the Tube system for the Colony project.
///
abstract class Hub : Structure
{
#region Fields
// Enumeration of the directions
public enum Directions
{
Positive_Y,
Positive_X,
Negative_Y,
Negative_X
}
// A list of the input carriers to distribute
protected List mInputCarriers;
// The array of tubes
Tube[] mTubes = new Tube[4];
// The flow through the tubes
float[] mFlows = new float[4];
#endregion
#region Properties
///
/// Allows access to the array of Tubes.
///
protected Tube[] Tubes
{
get { return mTubes; }
}
///
/// Allows access to the array of flows.
///
protected float[] Flows
{
get { return mFlows; }
}
#endregion
#region Constructs
///
/// Base constructor
///
/// The Content Manager
/// The model name
/// The texture name
public Hub(ContentManager pContent, string pModelName,
string pTextureName)
: base(pContent, pModelName, pTextureName)
{
// Create the lists
mInputCarriers = new List();
}
#endregion
#region Behavior
///
/// Tick along for the turn.
///
public override void Tick()
{
// Distribute the carriers
DistributeCarriers();
// Clear the current input carriers
mInputCarriers.Clear();
}
///
/// Distributes the current Carriers into new Carriers, based
/// on what's needed.
///
public void DistributeCarriers()
{
// The tubes to output to
Dictionary outputs = new Dictionary();
// Get the output tubes
for(int i = 0; i < Tubes.Length; i++)
{
// Go through and get the tube at the coordinate
Tube tube = Tubes[i];
// Make sure it isn't null
if( tube != null && mFlows[i] > 0 )
{
// See if it is facing the right way to be an output tube, and it's not null
if ((tube.GridPosition.X < this.GridPosition.X && tube.Running == Tube.Runnings.Negative_X) ||
(tube.GridPosition.X > this.GridPosition.X && tube.Running == Tube.Runnings.Positive_X) ||
(tube.GridPosition.Y < this.GridPosition.Y && tube.Running == Tube.Runnings.Negative_Y) ||
(tube.GridPosition.Y > this.GridPosition.Y && tube.Running == Tube.Runnings.Positive_Y))
{
// Add the tube
outputs.Add(tube, Flows[i]);
}
}
}
// Take the current carriers and split them as needed
foreach (Carrier carrier in mInputCarriers)
{
// Add a new carrier for each output tube
foreach (Tube tube in outputs.Keys)
{
// Create a new carrier with the same graphics as the previous
Carrier newCarrier = new Carrier(this.Content, carrier.ModelPath, carrier.TexturePath);
// Get the resource of the old carrier
Resource resource = carrier.Resource.Clone();
resource.Amount = (int)(resource.Amount * outputs[tube]);
// Now set the values of the carrier to match that of the old carrier
newCarrier.Resource = resource;
newCarrier.NumberOfTurns = carrier.NumberOfTurns;
newCarrier.TransformationMatrix = Matrix.CreateTranslation(tube.TransformationMatrix.Translation);
newCarrier.GridPosition = tube.GridPosition;
newCarrier.DrawOrder = tube.DrawOrder - 1;
// Call the tube to accept it
tube.ReceiveCarrier(newCarrier);
// Add the new carrier to the output list
GridReference.AddCarrier(newCarrier);
}
}
}
///
/// Receive the given Carrier.
///
/// The carrier to receive.
/// Whether we received the carrier or not
public override bool ReceiveCarrier(Carrier pCarrier)
{
// Add the carrier to our list of Carriers
mInputCarriers.Add(pCarrier);
// Dispose of the Carrier
pCarrier.Dispose();
// Add the carrier to our list of carriers
return base.ReceiveCarrier(pCarrier);
}
#endregion
#region Utility
///
/// Add the given tube and flow amount to the Hub.
///
/// The tube to add
/// The direction to add it on
public void AddTube(Tube pTube, Directions pDirection)
{
// Add the tube
mTubes[(int)pDirection] = pTube;
mFlows[(int)pDirection] = 1.0f;
}
public bool TubeExists(Directions pDirection)
{
return mTubes[(int)pDirection] != null;
}
///
/// Return the flow of at the given index.
///
/// The direction to look.
/// The flow for that direction.
public float GetFlow(Directions pDirection)
{
return mFlows[(int)pDirection];
}
///
/// Sets the flow for a given direction.
///
/// The flow amount.
/// The direction of flow.
public void SetFlow(float pFlow, Directions pDirection)
{
// Set the flow
mFlows[(int)pDirection] = pFlow;
}
///
/// Removes the given tube from the list.
///
/// The tube to remove.
public void RemoveTube(Tube tube)
{
// Go through and find the tube
for (int i = 0; i < mTubes.Length; i++)
{
// If it is the same tube
if (tube == mTubes[i])
{
// Set the tube to null
mTubes[i] = null;
mFlows[i] = 0.0f;
}
}
}
#endregion
}
}