// Here we initialize our app.
        public override void Setup()
        {
            //Init Hashtables
            cHash = new Hashtable();
            pHash = new Hashtable();
            eHash = new Hashtable();

            int i = 0;

            // Load up the list of images.
            mImageNames = LoadImageIndex();
            mDripNames = LoadDripIndex("r");
            mPdripNames = LoadPdripIndex("r");
            mYDripNames = LoadDripIndex("y");
            mYPdripNames = LoadPdripIndex("y");
            mBDripNames = LoadDripIndex("b");
            mBPdripNames = LoadPdripIndex("b");
            mBEcoliNames = LoadEColiIndex("b");
            mREcoliNames = LoadEColiIndex("r");
            mYEcoliNames = LoadEColiIndex("y");
            mEcoliNames = LoadEColiIndex("w");
            mEcoliTravelNames = LoadSameEColiTravelIndex("w");
            mBEcoliTravelNames = LoadSameEColiTravelIndex("b");
            mREcoliTravelNames = LoadSameEColiTravelIndex("r");
            mYEcoliTravelNames = LoadSameEColiTravelIndex("y");

            mBYEcoliTravelNamesC1 = LoadMixC1EcoliTravelIndex("b", "y");
            mBYEcoliTravelNamesC2 = LoadMixC2EcoliTravelIndex("b", "y");

            mRBEcoliTravelNamesC1 = LoadMixC1EcoliTravelIndex("r", "b");
            mRBEcoliTravelNamesC2 = LoadMixC2EcoliTravelIndex("r", "b");

            mRYEcoliTravelNamesC1 = LoadMixC1EcoliTravelIndex("r", "y");
            mRYEcoliTravelNamesC2 = LoadMixC2EcoliTravelIndex("r", "y");

            mWBEcoliTravelNamesC1 = LoadMixC1EcoliTravelIndex("w", "b");
            mWBEcoliTravelNamesC2 = LoadMixC2EcoliTravelIndex("w", "b");

            mWREcoliTravelNamesC1 = LoadMixC1EcoliTravelIndex("w", "r");
            mWREcoliTravelNamesC2 = LoadMixC2EcoliTravelIndex("w", "r");

            mWYEcoliTravelNamesC1 = LoadMixC1EcoliTravelIndex("w", "y");
            mWYEcoliTravelNamesC2 = LoadMixC2EcoliTravelIndex("w", "y"); 


            Array.Sort(mDripNames);
            Array.Sort(mPdripNames);
            Array.Sort(mYDripNames);
            Array.Sort(mYPdripNames);
            Array.Sort(mBDripNames);
            Array.Sort(mBPdripNames);
            Array.Sort(mBEcoliNames);
            Array.Sort(mREcoliNames);
            Array.Sort(mYEcoliNames);
            Array.Sort(mEcoliNames);
            Array.Sort(mEcoliTravelNames);
            Array.Sort(mBEcoliTravelNames);
            Array.Sort(mREcoliTravelNames);
            Array.Sort(mYEcoliTravelNames);
            Array.Sort(mBYEcoliTravelNamesC1);
            Array.Sort(mBYEcoliTravelNamesC2);
            Array.Sort(mRBEcoliTravelNamesC1);
            Array.Sort(mRBEcoliTravelNamesC2);
            Array.Sort(mRYEcoliTravelNamesC1);
            Array.Sort(mRYEcoliTravelNamesC2);
            Array.Sort(mWBEcoliTravelNamesC1);
            Array.Sort(mWBEcoliTravelNamesC2);
            Array.Sort(mWREcoliTravelNamesC1);
            Array.Sort(mWREcoliTravelNamesC2);
            Array.Sort(mWYEcoliTravelNamesC1);
            Array.Sort(mWYEcoliTravelNamesC2);


            //Init the StateMachine
            sm = new StateMachine();

            //Init the Controllers
            whitePlasmidController = new PlasmidController(this);
            yellowPlasmidController = new YellowPlasmidController(this);
            redPlasmidController = new RedPlasmidController (this);
            bluePlasmidController = new BluePlasmidController(this);

            sm.State("White", whitePlasmidController);
            sm.State("Yellow", yellowPlasmidController);
            sm.State("Red", redPlasmidController);
            sm.State("Blue", bluePlasmidController);

            sm.Transition("White", tWhiteToYellow, "Yellow");
            sm.Transition("White", tWhiteToRed, "Red");
            sm.Transition("White", tWhiteToBlue, "Blue");

            sm.SetState("White", tWhiteToYellow);
            

            //Log.Debug("mImageNames Length: " + mImageNames.Length);
            //Log.Debug("mDripNames Length: " + mDripNames.Length);
            //Log.Debug("mPdripNames Length: " + mPdripNames.Length);
            //Log.Debug("mYDripNames Length: " + mYDripNames.Length);
            //Log.Debug("mYPdripNames Length: " + mYPdripNames.Length);
            //Log.Debug("mBDripNames Length: " + mBDripNames.Length);
            //Log.Debug("mBPdripNames Length: " + mBPdripNames.Length);


            // Loop through all the cubes and set them up.\
            foreach (Cube cube in CubeSet)
            {
                // Create a wrapper object for each cube. The wrapper object allows us
                // to bundle a cube with extra information and behavior.
                CubeWrapper wrapper = new CubeWrapper(this, cube);

                wrapper.mCubeType = i % 3; //set each cube as a cube type 
                i++;

                //wrapper.mCubeType = 2;

                mWrappers.Add(wrapper);
                

                //grab the UniqueId of the proper cubes
                //if (wrapper.mCubeType == 0) cId = wrapper.mCube.UniqueId;
                //if (wrapper.mCubeType == 1) pId = wrapper.mCube.UniqueId;
                //if (wrapper.mCubeType == 2) eId = wrapper.mCube.UniqueId;

                //sort each cube into appropriate hashtables & update CubeWrapper information
                if (wrapper.mCubeType == 0)
                {
                    wrapper.cCubeWrapper = wrapper;
                    wrapper.cCubeStringId = cube.UniqueId;
                    wrapper.DrawColoredCube();
                    cHash.Add(wrapper.mCube.UniqueId, wrapper);
                    continue;
                }
                    
                if (wrapper.mCubeType == 1)
                {
                    wrapper.pCubeWrapper = wrapper;
                    wrapper.pCubeStringId = cube.UniqueId;
                    wrapper.DrawPlasmidCube();
                    pHash.Add(wrapper.mCube.UniqueId, wrapper);
                    continue;
                }
                    
                if (wrapper.mCubeType == 2)
                {
                    wrapper.eCubeWrapper = wrapper;
                    wrapper.eCubeStringId = cube.UniqueId;
                    wrapper.DrawEcoliCube();
                    eHash.Add(wrapper.mCube.UniqueId, wrapper);
                    continue;                    
                }    
                
            }

            //## Event Handlers ##
            // Objects in the Sifteo API (particularly BaseApp, CubeSet, and Cube)
            // fire events to notify an app of various happenings, including actions
            // that the player performs on the cubes.
            //
            // To listen for an event, just add the handler method to the event. The
            // handler method must have the correct signature to be added. Refer to
            // the API documentation or look at the examples below to get a sense of
            // the correct signatures for various events.
            //
            // **NeighborAddEvent** and **NeighborRemoveEvent** are triggered when
            // the player puts two cubes together or separates two neighbored cubes.
            // These events are fired by CubeSet instead of Cube because they involve
            // interaction between two Cube objects. (There are Cube-level neighbor
            // events as well, which comes in handy in certain situations, but most
            // of the time you will find the CubeSet-level events to be more useful.)

            CubeSet.NeighborAddEvent += OnNeighborAdd;
            CubeSet.NeighborRemoveEvent += OnNeighborRemove;

            //Init client
            _client = new Client();

            
        }
        /// <summary>
        ///  This method is called every frame by the Tick in SlideShowApp (see above.)
        /// </summary>
        public void Tick()
        {
            
            if (mCube.Neighbors.Bottom != null) //updating Plasmid cube
            {
                bCube = mCube.Neighbors.Bottom;
                bCubeWrapper = (CubeWrapper) bCube.userData;
            }

            if (mCube.Neighbors.Right != null) 
            {
                rCube = mCube.Neighbors.Right;
                rCubeWrapper = (CubeWrapper)rCube.userData; 
            }
            if (mCube.Neighbors.Left != null)
            {
                lCube = mCube.Neighbors.Left;
                lCubeWrapper = (CubeWrapper)lCube.userData;
            }

            //Iterate through Hashtables to find colored/plasmid/eColi CubeWrappers

            foreach (DictionaryEntry pair in mApp.cHash)
            {
                if (cCubeStringId != "")
                {
                    if (cCubeStringId == (string) pair.Key) cCubeWrapper = (CubeWrapper)pair.Value;
                }
            }

            foreach(DictionaryEntry pair in mApp.eHash)
            {
                if (eCubeStringId != "")
                {
                    if (eCubeStringId == (string) pair.Key) eCubeWrapper = (CubeWrapper)pair.Value;
                }
            }

            foreach (DictionaryEntry pair in mApp.pHash)
            {
                if (pCubeStringId != "")
                {
                    if (pCubeStringId == (string) pair.Key) pCubeWrapper = (CubeWrapper)pair.Value;
                }
            }

            // If anyone has raised the mNeedDrawDrip flag, draw the dripping.
            if (mNeedDrawDrip)
            {
                //Log.Debug("DrawDrip is called here");
                #region TEST
                //Log.Debug("Plasmid Name: " + plasmidName);
                //if (this.color == "red")
                //{
                //    for (int i = 0; i < mApp.mDripNames.Length; i++)
                //    {
                //        this.mIndex++;
                //        if (!(bIndex >= mApp.mPdripNames.Length)) this.bIndex++;
                //        else plasmidName = mApp.mPdripNames[mApp.mPdripNames.Length - 1];
                //        this.DrawDrip();
                //        this.DrawPdrip();
                //    }
                //}

                //if (this.color == "blue")
                //{
                //    for (int i = 0; i < mApp.mBDripNames.Length; i++)
                //    {
                //        this.mIndex++;
                //        if (!(bIndex >= mApp.mBPdripNames.Length)) this.bIndex++;
                //        else plasmidName = mApp.mBPdripNames[mApp.mBPdripNames.Length - 1];
                //        this.DrawDrip();
                //        this.DrawPdrip();
                //    }

                //}

                //if (this.color == "yellow")
                //{
                //    for (int i = 0; i < mApp.mYDripNames.Length; i++)
                //    {
                //        this.mIndex++;
                //        if (!(bIndex >= mApp.mYPdripNames.Length)) this.bIndex++;
                //        else plasmidName = mApp.mYPdripNames[mApp.mYPdripNames.Length - 1];
                //        this.DrawDrip();
                //        this.DrawPdrip();
                //    }

                //}
                #endregion

                this.DrawDrip();
                this.DrawPdrip();

            }

            if (mEcoliTravel)
            {
                for (int i = 0; i < mApp.mEcoliTravelNames.Length; i++)
                {   
                    travelIndex++;
                    if (travelIndex >= mApp.mEcoliTravelNames.Length)
                    {
                        travelIndex = 0;
                        break;
                    }
                    this.DrawEcoliTravel();
                }

                mEcoliTravel = false;
                
                //do
                //{
                //    travelIndex++;
                //    this.DrawEcoliTravel();
                //}
                //while (!(travelIndex > mApp.mEcoliTravelNames.Length));

                
            }

        }