/// <summary>
        /// Setup constructor
        /// </summary>
        /// <param name="view">Terrain type list view</param>
        /// <param name="model">Terrain type model. Can be null</param>
        /// <exception cref="System.ArgumentNullException">Thrown if view is null</exception>
        public TerrainTypeListController( TerrainTypeList model, ITerrainTypeListView view )
        {
            Arguments.CheckNotNull( view, "view" );

            m_View = view;
            view.AddTerrainType += OnAddTerrainType;
            view.RemoveTerrainType += OnRemoveTerrainType;

            Model = model;
        }
        /// <summary>
        /// Default constructor. Creates a background thread to process new texture requests
        /// </summary>
        public TerrainTypeTextureBuilder( TerrainTypeList terrainTypes )
        {
            Arguments.CheckNotNull( terrainTypes , "terrainTypes");
            m_Worker = new BackgroundWorker( );
            m_Worker.DoWork += ProcessRequest;
            m_Worker.RunWorkerCompleted += RequestComplete;
            m_LookupTexture = RbGraphics.Factory.CreateTexture2d( );
            m_PackTexture = RbGraphics.Factory.CreateTexture2d( );

            TerrainTypes = terrainTypes;
        }
        /// <summary>
        /// Builds a bitmap of the specified dimensions, using a terrain type set to colour the underlying heightmap
        /// </summary>
        public unsafe Bitmap Build( int width, int height, TerrainTypeList terrainTypes )
        {
            if ( terrainTypes.TerrainTypeCount == 0 )
            {
                return Build( width, height );
            }

            Bitmap bmp = new Bitmap( width, height, PixelFormat.Format24bppRgb );

            BitmapData bmpData = bmp.LockBits( new System.Drawing.Rectangle( 0, 0, width, height ), ImageLockMode.WriteOnly, bmp.PixelFormat );
            byte* rowFirstPixel = ( byte* )bmpData.Scan0;

            float[,] heights = GetHeights( width, height );
            float[,] lighting = GetLighting( width, height );
            float[,] slopes = GetSlopes( width, height );

            for ( int row = 0; row < height; ++row )
            {
                byte* curPixel = rowFirstPixel;
                for ( int col = 0; col < width; ++col )
                {
                    float h = heights[ col, row ];
                    float s = slopes[ col, row ];
                    float l = ApplyLighting ? lighting[ col, row ] : 1.0f;
                    Color c = terrainTypes.GetType( h, s ).AverageColour;
                    curPixel[ 0 ] = ( byte )( c.B * l );
                    curPixel[ 1 ] = ( byte )( c.G * l );
                    curPixel[ 2 ] = ( byte )( c.R * l );
                    curPixel += 3;
                }

                rowFirstPixel += bmpData.Stride;
            }

            bmp.UnlockBits( bmpData );
            return bmp;
        }
 /// <summary>
 /// Clones this set
 /// </summary>
 public TerrainTypeList Clone( )
 {
     TerrainTypeList clone = new TerrainTypeList( );
     foreach ( TerrainType srcType in m_TerrainTypes )
     {
         clone.m_TerrainTypes.Add( srcType.Clone( ) );
     }
     return clone;
 }