5 Replies - 822 Views - Last Post: 22 May 2014 - 04:58 PM Rate Topic: -----

#1 chiba   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 32
  • Joined: 23-December 13

BeeHive Simulator - Bees don't move

Posted 22 May 2014 - 12:03 PM

I have attached the c# project as a zipped archive.

Would appreciate if someone might be able to help me debug?

The bees just flap their wings and don't move from the hive. Their location property is being changed , but this is not resulting in them moving... :surrender:
Is This A Good Question/Topic? 0
  • +

Replies To: BeeHive Simulator - Bees don't move

#2 modi123_1   User is offline

  • Suitor #2
  • member icon



Reputation: 14045
  • View blog
  • Posts: 56,218
  • Joined: 12-June 08

Re: BeeHive Simulator - Bees don't move

Posted 22 May 2014 - 12:06 PM

You didn't seem to attach a file. How about showing us the relevant code for their movement and drawing?
Was This Post Helpful? 0
  • +
  • -

#3 modi123_1   User is offline

  • Suitor #2
  • member icon



Reputation: 14045
  • View blog
  • Posts: 56,218
  • Joined: 12-June 08

Re: BeeHive Simulator - Bees don't move

Posted 22 May 2014 - 12:42 PM

Soooooo.. you aren't going to just post the relevant code for movement and drawing? As much as I enjoy foreign zip files with questionable payloads, I would much prefer just seeing the code on the screen (versus having folks download it, scan it, unzip it, sort through it, etc).
Was This Post Helpful? 0
  • +
  • -

#4 chiba   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 32
  • Joined: 23-December 13

Re: BeeHive Simulator - Bees don't move

Posted 22 May 2014 - 02:51 PM

Bee
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Diagnostics;

namespace TheHive
{
    [Serializable]
    class Bee
    {
        private const double HoneyConsumed = 0.5;
        private const int MoveRate = 3;
        private const double MinimumFlowerNectar = 1.5;
        private const int CareerSpan = 1000;

        public int Age { get; private set; }
        public bool InsideHive { get; private set;  }
        public double NectarCollected { get; private set; }
        public BeeState CurrentState { get; private set; }

        private Point location;
        public Point Location { get { return location; } }

        private int ID;
        private Flower destinationFlower;

        private Hive hive;
        private World world;

        [NonSerialized] public MessageSender ms;

        public Bee(int id, Point location, Hive hive, World world)
        {
            this.ID = id;
            Age = 0;
            this.location = location;
            InsideHive = true;
            destinationFlower = null;
            NectarCollected = 0;
            CurrentState = BeeState.Idle;
            this.hive = hive;
            this.world = world;
        }

        public void Go(Random random)
        {
            Age++;
            BeeState oldState = CurrentState;
            switch (CurrentState)
            {
                case BeeState.Idle:
                {
                    if (Age > CareerSpan)
                    {
                        CurrentState = BeeState.Retired;
                    }
                    else if (world.Flowers.Count > 0 && hive.ConsumeHoney(HoneyConsumed))
                    {
                        Flower flower = world.Flowers[random.Next(world.Flowers.Count)];
                        if (flower.Nectar >= MinimumFlowerNectar && flower.Alive)
                        {
                            destinationFlower = flower;
                            CurrentState = BeeState.FlyingToFlower;
                        }
                    }
                    break;
                }
                
                case BeeState.FlyingToFlower:  
                {
                    if (!(world.Flowers.Contains(destinationFlower)))
                        CurrentState = BeeState.ReturningToHive;
                    else if (InsideHive)
                    {
                        if (MoveTowardsLocation(hive.GetLocation("Exit")))
                        {
                            InsideHive = false;
                            //Debug.WriteLine("Bee" + ID + " - InsideHive: " + InsideHive);
                            location = hive.GetLocation("Entrance");
                        }
                    }
                    else
                    {
                        if (MoveTowardsLocation(destinationFlower.Location))
                            CurrentState = BeeState.GatheringNectar;
                    }
                    break;
                }
                
                case BeeState.GatheringNectar:  
                {
                    double nectar = destinationFlower.HarvestNectar();
                    if (nectar > 0)
                        NectarCollected += nectar;
                    else
                        CurrentState = BeeState.ReturningToHive;
                    break; 
                }

                case BeeState.MakingHoney:  
                {
                    if (NectarCollected < 0.5)
                    {
                        NectarCollected = 0;
                        CurrentState = BeeState.Idle;
                    }
                    else
                    {
                        // turn nectar to honey
                        if (hive.AddHoney(0.5))
                            NectarCollected -= 0.5;
                        else
                            NectarCollected = 0;
                    }
                    break; 
                }

                case BeeState.Retired:  
                { 
                    // do nothing
                    break; 
                }

                case BeeState.ReturningToHive:  
                {
                    if (!InsideHive)
                    {
                        //move towards hive
                        if (MoveTowardsLocation(hive.GetLocation("Entrance")))
                        {
                            InsideHive = true;
                            location = hive.GetLocation("Exit");
                        }
                    }
                    else
                    {
                        // what to do inside hive
                        if (MoveTowardsLocation(hive.GetLocation("HoneyFactory")))
                            CurrentState = BeeState.MakingHoney;
                    }
                    break; 
                }
            }
            // if bees state changes , send the new state to the method in the form
            if (oldState != CurrentState && ms != null)
            {
                ms(ID, CurrentState.ToString() );
                Debug.WriteLine("Bee " + ID + " " + location.X.ToString() + " " + location.Y.ToString() + " flying to" + destinationFlower.Location.X);
            }
        }

        private bool MoveTowardsLocation(Point destination)
        {
            if (Math.Abs(destination.X - location.X) <= MoveRate && Math.Abs(destination.Y - location.Y) <=MoveRate)
            {
                return true;
            }

            if (destination.X > location.X)
            {
                location.X += MoveRate;
            }
            else if (destination.X < location.X)
            {
                location.X -= MoveRate;
            }

            if (destination.Y > location.Y)
                location.Y += MoveRate;
            else if (destination.Y < location.Y)
                location.Y -= MoveRate;

            return false;
        }
    }
}




BeeControl
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace TheHive
{
    public partial class BeeControl : UserControl
    {
        public BeeControl()
        {
            InitializeComponent();
            BackColor = System.Drawing.Color.Transparent;
            BackgroundImageLayout = ImageLayout.Stretch;
            ResizeCells();
            DoubleBuffered = true;
        }
        private Bitmap[] cells = new Bitmap[4];

        private void ResizeCells()
        {
            cells[0] = Renderer.ResizeImage(Properties.Resources.Bee_animation_1, this.Width, this.Height);
            cells[1] = Renderer.ResizeImage(Properties.Resources.Bee_animation_2, this.Width, this.Height);
            cells[2] = Renderer.ResizeImage(Properties.Resources.Bee_animation_3, this.Width, this.Height);
            cells[3] = Renderer.ResizeImage(Properties.Resources.Bee_animation_4, this.Width, this.Height);
        }

        private int cell = 0;

        private void animationTimer_Tick_1(object sender, EventArgs e)
        {
            cell++;
            switch (cell)
            {
                case 1: BackgroundImage = cells[0]; break;
                case 2: BackgroundImage =  cells[1]; break;
                case 3: BackgroundImage =  cells[2]; break;
                case 4: BackgroundImage =  cells[3]; break;
                case 5: BackgroundImage = cells[2]; break;
                default: BackgroundImage = cells[1];
                    cell = 0; break;
            }
        }

        private void BeeControl_Resize(object sender, EventArgs e)
        {
            ResizeCells();
        }
    }
}




Hive
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace TheHive
{
    [Serializable]
    class Hive
    {
        public double Honey { private set; get; }
        private Dictionary<string, Point> locations;
        private int beeCount=0;

        private const int initalBees = 6;
        private const double startHoney = 3.2;
        private const double maxHoney = 15.0;
        private const double nectarHoneyRatio = 0.25;
        private const int maxBees = 8;
        private const double minToBirth = 4.0;

        private Random random;

        private World world;

        [NonSerialized] public MessageSender ms;

        public Hive(World world, MessageSender ms)
        {
            this.ms = ms;
            Honey = startHoney;
            this.world = world;
            InitializeLocations();
            random = new Random();
            for (int i = 0; i < initalBees; i++ )
                AddBee(random);
        }

        public Point GetLocation(string location)
        {
            //Point point;
            //if (locations.TryGetValue(location, out point))
            //{
            //    return locations[location];
            //}
            //else
            //{
            //    throw new ArgumentException();
            //}
            if (locations.Keys.Contains(location))
                return locations[location];
            else
                throw new ArgumentException("Unknown location: " + location);
            
        }

        public void InitializeLocations()
        {
            locations = new Dictionary<string, Point>();

            Point entrance = new Point(80, 85);
            Point nursery = new Point(94, 158);
            Point honeyFactory = new Point(185, 74);
            Point exit = new Point(212, 194);

            locations.Add("Entrance", entrance);
            locations.Add("Nursery", nursery);
            locations.Add("HoneyFactory", honeyFactory);
            locations.Add("Exit", exit);

        }

        // Add bees
        public void AddBee(Random random)
        {
            
            beeCount++;
            int r1 = random.Next(100) - 50;
            int r2 = random.Next(100) - 50;
            Point startPoint = new Point(locations["Nursery"].X + r1, locations["Nursery"].Y + r2);
            Bee newBee = new Bee(beeCount, startPoint, this ,world);
            newBee.ms += this.ms;
            // add bee to world
            world.Bees.Add(newBee);

        }

        public bool ConsumeHoney(double amount)
        {
            if (amount > Honey)
            {
                return false;
            }
            else
            {
                Honey -= amount;
                return true;
            }
        }
        public bool AddHoney(double nectar)
        {
            double honeyToAdd = nectar * nectarHoneyRatio;
            if (honeyToAdd + Honey > maxHoney)
                return false;
            Honey += honeyToAdd;
            return true;
        }

        // Add bee
        public void Go(Random random)
        {
            if ((world.Bees.Count < maxBees) && (Honey > minToBirth) && (random.Next(10)==1))
                AddBee(random);
        }
    }
}




Renderer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace TheHive
{
    class Renderer
    {
        private World world;
        private HiveForm hiveForm;
        private FieldForm fieldForm;

        private Dictionary<Flower, PictureBox> flowerLookup = new Dictionary<Flower, PictureBox>();
        private List<Flower> deadFlowers = new List<Flower>();

        private Dictionary<Bee, BeeControl> beeLookup = new Dictionary<Bee, BeeControl>();
        private List<Bee> retiredBees = new List<Bee>();

        public Renderer(World world, HiveForm hiveForm, FieldForm fieldForm)
        {
            this.world = world;
            this.hiveForm = hiveForm;
            this.fieldForm = fieldForm;
        }

        public void Render()
        {
            DrawBees();
            DrawFlowers();
            RemoveRetiredBeesAndDeadFlowers();

        }

        public void Reset()
        {
            foreach (PictureBox flower in flowerLookup.Values)
            {
                fieldForm.Controls.Remove(flower);
                flower.Dispose();
            }

            foreach (BeeControl bee in beeLookup.Values)
            {
                fieldForm.Controls.Remove(bee);
                hiveForm.Controls.Remove(bee);
                bee.Dispose();
            }

            flowerLookup.Clear();
            beeLookup.Clear();
        }

        private void RemoveRetiredBeesAndDeadFlowers()
        {
            foreach (Bee bee in retiredBees)
            {
                beeLookup.Remove(bee);
            }
            retiredBees.Clear();
            foreach (Flower flower in deadFlowers)
            {
                flowerLookup.Remove(flower);
            }
            deadFlowers.Clear();
        }

        private void DrawFlowers()
        {
            foreach (Flower flower in world.Flowers)
            {
                if (!flowerLookup.ContainsKey(flower))
                {
                    PictureBox flowerControl = new PictureBox()
                    {
                        Width = 45,
                        Height = 55,
                        Image = Properties.Resources.Flower,
                        SizeMode = PictureBoxSizeMode.StretchImage,
                        Location = flower.Location
                    };
                    flowerLookup.Add(flower, flowerControl);
                    fieldForm.Controls.Add(flowerControl);
                }
            }

            foreach (Flower flower in flowerLookup.Keys)
            {
                if (!world.Flowers.Contains(flower))
                {
                    PictureBox flowerControlToRemove = flowerLookup[flower];
                    fieldForm.Controls.Remove(flowerControlToRemove);
                    flowerControlToRemove.Dispose();
                    deadFlowers.Add(flower);
                }
            }
        }

        private void DrawBees()
        {

            BeeControl beeControl;

            foreach (Bee bee in world.Bees)
            {
                //Debug.WriteLine(bee.
                beeControl = GetBeeControl(bee);
                if (bee.InsideHive)
                {
                    if (fieldForm.Controls.Contains(beeControl))
                        MoveBeeFromFieldToHive(beeControl);
                }
                else if (hiveForm.Controls.Contains(beeControl))
                {
                    MoveBeeFromHiveToField(beeControl);
                }
                beeControl.Location = bee.Location;
            }

            foreach (Bee bee in beeLookup.Keys)
            {
                if (!world.Bees.Contains(bee))
                {
                    beeControl = beeLookup[bee];
                    if (fieldForm.Controls.Contains(beeControl))
                        fieldForm.Controls.Remove(beeControl);
                    if (hiveForm.Controls.Contains(beeControl))
                        hiveForm.Controls.Remove(beeControl);
                    beeControl.Dispose();
                    retiredBees.Add(bee);
                }
            }


        }

        private BeeControl GetBeeControl(Bee bee)
        {
            BeeControl beeControl;
            if (!beeLookup.ContainsKey(bee))
            {
                beeControl = new BeeControl() { Width = 40, Height = 40 };
                beeLookup.Add(bee, beeControl);
                hiveForm.Controls.Add(beeControl);
                beeControl.BringToFront();
            }
            else
            {
                beeControl = beeLookup[bee];
            }
            return beeControl;
        }

        private void MoveBeeFromFieldToHive(BeeControl beeControl)
        {
            // From Field To Hive
            fieldForm.Controls.Remove(beeControl);
            beeControl.Size = new Size(40,40);
            hiveForm.Controls.Add(beeControl);
            beeControl.BringToFront();
        }

        private void MoveBeeFromHiveToField(BeeControl beeControl)
        {
            // From Hive To Field
            hiveForm.Controls.Remove(beeControl);
            beeControl.Size = new Size(20, 20);
            fieldForm.Controls.Add(beeControl);
            beeControl.BringToFront();
        }

        public static Bitmap ResizeImage(Bitmap picture, int width, int height)
        {
            Bitmap resizedPicture = new Bitmap(width,height);
            using (Graphics graphics = Graphics.FromImage(resizedPicture))
            {
                graphics.DrawImage(picture, 0,0, width,height);
            }
            return resizedPicture;
        }
    }
}



World
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace TheHive
{
    [Serializable]
    class World
    {
        private const double NectarHarvestedPerFlower = 50.0;

        private const int FieldMinX = 15;
        private const int FieldMinY = 177;
        private const int FieldMaxX = 690;
        private const int FieldMaxY = 290;

        public Hive Hive;
        public List<Bee> Bees;
        public List<Flower> Flowers;



        public World(MessageSender ms)
        {
            Bees = new List<Bee>();
            Flowers = new List<Flower>();
            Random random = new Random();
            Hive = new Hive(this, ms);

            for (int i = 0; i < 10; i++)
                AddFlower(random);
        }

        public void Go(Random random)
        {
            Hive.Go(random);

            for (int i = Bees.Count - 1; i >= 0; i-- )
            {
                Bee bee =Bees[i];
                bee.Go(random);
                if (bee.CurrentState==BeeState.Retired)
                    Bees.Remove(bee);
            }

            double totalNectarHarvested = 0;
            for (int i=Flowers.Count -1; i >=0; i--)
            {
                Flower flower = Flowers[i];
                flower.Go();
                totalNectarHarvested += flower.NectarHarvested;
                if (!flower.Alive)
                    Flowers.Remove(flower);
            }

            if (totalNectarHarvested>NectarHarvestedPerFlower)
            {
                foreach (Flower flower in Flowers)
                    flower.NectarHarvested = 0;
                AddFlower(random);
            }
        }

        private void AddFlower(Random random)
        {
            // exception here
            Point location = new Point(random.Next(FieldMinX,FieldMaxX),random.Next(FieldMinY,FieldMaxY));
            Flower newFlower = new Flower(location, random);
            Flowers.Add(newFlower);
        }
    }
}



form1
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Drawing.Drawing2D;

namespace TheHive
{
    public partial class Form1 : Form
    {
        private World world;
        private Random random = new Random();
        private DateTime start = DateTime.Now;
        private DateTime end;
        private int framesRun = 0;

        private HiveForm hiveForm = new HiveForm();
        private FieldForm fieldForm = new FieldForm();
        private Renderer renderer;

        public Form1()
        {
            InitializeComponent();

            MoveChildForms();
            hiveForm.Show(this);
            fieldForm.Show(this);
            ResetSimulator();
            // reference to method passed as parameter
            world = new World(new MessageSender(SendMessage));
            timer1.Interval = 50;
            timer1.Tick += new EventHandler(RunFrame);
            timer1.Enabled = false;
            // constructing
            UpdateStats(new TimeSpan());
            statusStrip1.Items[0].Text = "";
            
        }

        private void ResetSimulator()
        {
            framesRun = 0;
            world = new World(new MessageSender(SendMessage));
            renderer = new Renderer(world, hiveForm, fieldForm);
        }

        private void MoveChildForms()
        {
            hiveForm.Location = new Point(Location.X + Width + 10, Location.Y);
            fieldForm.Location = new Point(Location.X, Location.Y + Math.Max(Height, hiveForm.Height) + 10);
        }

        public void RunFrame(object sender, EventArgs e)
        {
            framesRun++;
            world.Go(random);
            renderer.Render();
            end = DateTime.Now;
            TimeSpan frameDuration = end - start;
            start = end;
            UpdateStats(frameDuration);
        }

        private void UpdateStats(TimeSpan frameDuration)
        {
            BeesLabel.Text = world.Bees.Count.ToString();
            FlowersLabel.Text = world.Flowers.Count.ToString();
            HoneyInHiveLabel.Text = String.Format("{0:f3}", world.Hive.Honey);
            double nectar = 0;
            foreach (Flower flower in world.Flowers)
                nectar += flower.Nectar;
            NectarInFlowersLabel.Text = String.Format("{0:f3}", nectar);
            FramesRunLabel.Text = framesRun.ToString();
            double milliSeconds = frameDuration.TotalMilliseconds;
            if (milliSeconds != 0.0)
                FrameRateLabel.Text = string.Format("{0:f0} {1:f1}ms", 1000 / milliSeconds, milliSeconds);
            else
                FrameRateLabel.Text = "N/A";

        }

        private void startSimulation_Click(object sender, EventArgs e)
        {
            if (timer1.Enabled)
            {
                timer1.Stop();
                statusStrip1.Items[0].Text = "Simulation paused";
                startSimulation.Text = "Resume Simulation";
            }
            else
            {
                timer1.Start();
                startSimulation.Text = "Pause Simulation";
                statusStrip1.Items[0].Text = "";
            }
            
            
        }

        private void resetSimulation_Click(object sender, EventArgs e)
        {
            renderer.Reset();
            ResetSimulator();
            if (!timer1.Enabled)
                startSimulation.Text = "Start Simulation";
            //statusStrip1.Text = "";

            // recreate world
            world = new World(new MessageSender(SendMessage));
            framesRun = 0;
        }


        private void SendMessage(int ID, string message)
        {
            //update status strip
            statusStrip1.Items[0].Text = "Bee #" + ID + ": " + message;
            //LINQ query
            var beeGroups =
                from bee in world.Bees
                group bee by bee.CurrentState into beeGroup
                orderby beeGroup.Key
                select beeGroup;
            listBox1.Items.Clear();
            foreach (var group in beeGroups)
            {
                string s;
                if (group.Count() == 1)
                    s = "";
                else
                    s = "s";
                listBox1.Items.Add(group.Key.ToString() + ": " + group.Count() + " bee" +s);
                if (group.Key==BeeState.Idle && group.Count() == world.Bees.Count() && framesRun >0)
                {
                    listBox1.Items.Add("Simulation ended: all bees are idle");
                    toolStrip1.Items[0].Text = "Simulation ended";
                    statusStrip1.Items[0].Text = "Simulation ended";
                    timer1.Enabled = false;
                }
            }
        }

        private void saveToolStripButton_Click(object sender, EventArgs e)
        {
            bool enabled = timer1.Enabled;
            if (enabled)
                timer1.Stop();

            saveFileDialog1.Filter = "BeeHive (.beehive)|*.beehive";
            saveFileDialog1.FileName = "new_hive.beehive";
            DialogResult result = saveFileDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                try
                {

                    using (Stream output = File.Create(saveFileDialog1.FileName))
                    {
                        BinaryFormatter formatter = new BinaryFormatter();
                        formatter.Serialize(output, world);
                        formatter.Serialize(output, framesRun);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Save failed " + ex.Message, "Save Failed");
                }
            }
            if (enabled)
                timer1.Start();
        }

        private void openToolStripButton_Click(object sender, EventArgs e)
        {
            // make a reference to current world encase open fails
            World currentWorld = world;
            int currentFrames = framesRun;

            bool enabled = timer1.Enabled;
            if (enabled)
                timer1.Stop();

            //openFileDialog1.InitialDirectory = "";
            openFileDialog1.Filter = "BeeHive (.beehive)|*.beehive";
            openFileDialog1.CheckFileExists = true;
            openFileDialog1.CheckPathExists = true;
            openFileDialog1.Title = "Choose a file with a simulation to load";
            DialogResult result = openFileDialog1.ShowDialog();
            if (result == DialogResult.OK)
            {
                try
                {
                    using (Stream input = File.OpenRead(openFileDialog1.FileName))
                    {
                        BinaryFormatter formatter = new BinaryFormatter();
                        world = (World)formatter.Deserialize(input);
                        framesRun = (int)formatter.Deserialize(input);

                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("File open failed " + ex.Message, "File open Failed");
                    world = currentWorld;
                    framesRun = currentFrames;
                }
            }

            world.Hive.ms = new MessageSender(SendMessage);
            foreach (Bee bee in world.Bees)
                bee.ms = new MessageSender(SendMessage);
            if (enabled)
                timer1.Start();

            renderer.Reset();
            renderer = new Renderer(world, hiveForm, fieldForm);
        }

        private void Form1_Move(object sender, EventArgs e)
        {
            MoveChildForms();
        }

    }
}




Screen shot of simulator
Attached Image

This post has been edited by chiba: 22 May 2014 - 02:55 PM

Was This Post Helpful? 0
  • +
  • -

#5 modi123_1   User is offline

  • Suitor #2
  • member icon



Reputation: 14045
  • View blog
  • Posts: 56,218
  • Joined: 12-June 08

Re: BeeHive Simulator - Bees don't move

Posted 22 May 2014 - 03:03 PM

... is this from the Headfirst C# book?
Was This Post Helpful? 0
  • +
  • -

#6 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6532
  • View blog
  • Posts: 14,447
  • Joined: 02-June 10

Re: BeeHive Simulator - Bees don't move

Posted 22 May 2014 - 04:58 PM

Quote

Would appreciate if someone might be able to help me debug?


Debugging tutorials (several of them) are in FAQ 2.
But we won't do your homework for you.

TOP most asked:
What does this error message mean?
FAQ 2: How do I debug
FAQ 3: How do I make Class1/Form1 talk to Class2/Form2


FAQ (Frequently Asked Questions - Updated Feb 2014
Spoiler

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1