using System;
using System.Drawing;
using ClassicalSharp.GraphicsAPI;
namespace ClassicalSharp {
	
	///  Integer constants for the six tile sides of a block. 
	public static class TileSide {
		public const int Left = 0;
		public const int Right = 1;
		public const int Front = 2;
		public const int Back = 3;
		public const int Bottom = 4;
		public const int Top = 5;
		public const int Sides = 6;
	}
	
	///  Represents a 2D packed texture atlas, specifically for terrain.png. 
	public class TerrainAtlas2D : IDisposable {
		
		public const int ElementsPerRow = 16, RowsCount = 16;
		public const float invElementSize = 1 / 16f;
		public Bitmap AtlasBitmap;
		public int elementSize;
		public int TexId;
		IGraphicsApi graphics;
		IDrawer2D drawer;
		
		public TerrainAtlas2D( IGraphicsApi graphics, IDrawer2D drawer ) {
			this.graphics = graphics;
			this.drawer = drawer;
		}
		
		///  Updates the underlying atlas bitmap, fields, and texture. 
		public void UpdateState( BlockInfo info, Bitmap bmp ) {
			if( !FastBitmap.CheckFormat( bmp.PixelFormat ) ) {
				Utils.LogDebug( "Converting terrain atlas to 32bpp image" );
				drawer.ConvertTo32Bpp( ref bmp );
			}
			
			AtlasBitmap = bmp;
			elementSize = bmp.Width >> 4;
			using( FastBitmap fastBmp = new FastBitmap( bmp, true ) ) {
				info.RecalculateSpriteBB( fastBmp );
				TexId = graphics.CreateTexture( fastBmp );
			}
		}
		
		///  Creates a new texture that contains the tile at the specified index. 
		public int LoadTextureElement( int index ) {
			int size = elementSize;			
			using( FastBitmap atlas = new FastBitmap( AtlasBitmap, true ) ) {
				using( Bitmap bmp = new Bitmap( size, size ) ) {
					
					using( FastBitmap dst = new FastBitmap( bmp, true ) ) {
						FastBitmap.MovePortion( (index & 0x0F) * size, (index >> 4) * 
						                       size, 0, 0, atlas, dst, size );
						return graphics.CreateTexture( dst );
					}
				}
			}
		}
		
		///  Gets a rectangle that describes the UV coordinates for 
		/// the tile at the specified index. 
		public TextureRec GetTexRec( int index ) {
			return new TextureRec( (index & 0x0F) * invElementSize, (index >> 4) * 
			                      invElementSize, invElementSize, invElementSize );
		}
		
		///  Gets a rectangle that describes the UV coordinates for 
		/// the tile at the specified index, adjusted to work for AMD/ATI cards. 
		public TextureRec GetAdjTexRec( int index ) {
			// Adjust coords to be slightly inside - fixes issues with AMD/ATI cards.
			const float invAdjSize = invElementSize * (15.99f/16f);
			return new TextureRec( (index & 0x0F) * invElementSize, (index >> 4) * 
			                      invElementSize, invAdjSize, invAdjSize );
		}
		
		///  Disposes of the underlying atlas bitmap and texture. 
		public void Dispose() {
			if( AtlasBitmap != null )
				AtlasBitmap.Dispose();
			graphics.DeleteTexture( ref TexId );
		}
	}
}