using System ;
using System.Collections.Generic ;
using System.Runtime.InteropServices ;
using System.Text ;


namespace DxLibDLL
{


	public static partial class DX
	{


		public interface IStream
		{

			int Tell() ;

			int Seek( int SeekPoint , STREAM_SEEKTYPE SeekType ) ;

			int Read( IntPtr Buffer , int BlockSize , int DataNum ) ;

			bool Eof() ;

			bool IdleCheck() ;

			void Close() ;
		}


		internal sealed class StreamData : IStream
		{

			public int Tell()
			{
				return this.data.ReadShred.Tell( this.data.DataPoint ) ;
			}

			public int Seek( int SeekPoint , STREAM_SEEKTYPE SeekType )
			{
				return this.data.ReadShred.Seek( this.data.DataPoint , SeekPoint , SeekType ) ;
			}

			public int Read( IntPtr Buffer , int BlockSize , int DataNum )
			{
				return ( int )( this.data.ReadShred.Read( Buffer , ( IntPtr )( BlockSize ) , ( IntPtr )( DataNum ) , this.data.DataPoint ) ) ;
			}

			public bool Eof()
			{
				return this.data.ReadShred.Eof( this.data.DataPoint ) ;
			}

			public bool IdleCheck()
			{
				return this.data.ReadShred.IdleCheck( this.data.DataPoint ) ;
			}

			public void Close()
			{
				this.data.ReadShred.Close( this.data.DataPoint ) ;
			}

			internal StreamData( STREAMDATA data )
			{
				this.data = data ;
			}

			private STREAMDATA data ;
		}


	#if UNICODE
		[ UnmanagedFunctionPointer( CallingConvention.Cdecl , CharSet = CharSet.Unicode ) ]
	#else
		[ UnmanagedFunctionPointer( CallingConvention.Cdecl , CharSet = CharSet.Ansi ) ]
	#endif
		internal delegate int STREAMDATASHRED_Tell( IntPtr StreamDataPoint ) ;

	#if UNICODE
		[ UnmanagedFunctionPointer( CallingConvention.Cdecl , CharSet = CharSet.Unicode ) ]
	#else
		[ UnmanagedFunctionPointer( CallingConvention.Cdecl , CharSet = CharSet.Ansi ) ]
	#endif
		internal delegate int STREAMDATASHRED_Seek( IntPtr StreamDataPoint , int SeekPoint , STREAM_SEEKTYPE SeekType ) ;

	#if UNICODE
		[ UnmanagedFunctionPointer( CallingConvention.Cdecl , CharSet = CharSet.Unicode ) ]
	#else
		[ UnmanagedFunctionPointer( CallingConvention.Cdecl , CharSet = CharSet.Ansi ) ]
	#endif
		internal delegate IntPtr STREAMDATASHRED_Read( IntPtr Buffer , IntPtr BlockSize , IntPtr DataNum , IntPtr StreamDataPoint ) ;

	#if UNICODE
		[ UnmanagedFunctionPointer( CallingConvention.Cdecl , CharSet = CharSet.Unicode ) ]
	#else
		[ UnmanagedFunctionPointer( CallingConvention.Cdecl , CharSet = CharSet.Ansi ) ]
	#endif
		internal delegate bool STREAMDATASHRED_Eof( IntPtr StreamDataPoint ) ;

	#if UNICODE
		[ UnmanagedFunctionPointer( CallingConvention.Cdecl , CharSet = CharSet.Unicode ) ]
	#else
		[ UnmanagedFunctionPointer( CallingConvention.Cdecl , CharSet = CharSet.Ansi ) ]
	#endif
		internal delegate bool STREAMDATASHRED_IdleCheck( IntPtr StreamDataPoint ) ;

	#if UNICODE
		[ UnmanagedFunctionPointer( CallingConvention.Cdecl , CharSet = CharSet.Unicode ) ]
	#else
		[ UnmanagedFunctionPointer( CallingConvention.Cdecl , CharSet = CharSet.Ansi ) ]
	#endif
		internal delegate int STREAMDATASHRED_Close( IntPtr StreamDataPoint ) ;

		/// <summary> ストリームデータ制御用関数ポインタ構造体 </summary>
	#if UNICODE
		[ StructLayout( LayoutKind.Sequential , CharSet = CharSet.Unicode ) ]
	#else
		[ StructLayout( LayoutKind.Sequential , CharSet = CharSet.Ansi ) ]
	#endif
		internal struct STREAMDATASHRED
		{

			[ MarshalAs( UnmanagedType.FunctionPtr ) ]
			public STREAMDATASHRED_Tell Tell ;

			[ MarshalAs( UnmanagedType.FunctionPtr ) ]
			public STREAMDATASHRED_Seek Seek ;

			[ MarshalAs( UnmanagedType.FunctionPtr ) ]
			public STREAMDATASHRED_Read Read ;

			[ MarshalAs( UnmanagedType.FunctionPtr ) ]
			public STREAMDATASHRED_Eof Eof ;

			[ MarshalAs( UnmanagedType.FunctionPtr ) ]
			public STREAMDATASHRED_IdleCheck IdleCheck ;

			[ MarshalAs( UnmanagedType.FunctionPtr ) ]
			public STREAMDATASHRED_Close Close ;
		}


		/// <summary> ストリームデータ制御用データ構造体 </summary>
	#if UNICODE
		[ StructLayout( LayoutKind.Sequential , CharSet = CharSet.Unicode ) ]
	#else
		[ StructLayout( LayoutKind.Sequential , CharSet = CharSet.Ansi ) ]
	#endif
		internal struct STREAMDATA
		{

			public STREAMDATASHRED ReadShred ;

			public IntPtr DataPoint ;


			public STREAMDATA( IStream source )
			{
				this.ReadShred = new STREAMDATASHRED() ;
				this.DataPoint = IntPtr.Zero ;

				this.ReadShred.Tell = delegate( IntPtr StreamDataPoint )
				{
					return source.Tell() ;
				} ;

				this.ReadShred.Seek = delegate( IntPtr StreamDataPoint , int SeekPoint , STREAM_SEEKTYPE SeekType )
				{
					return source.Seek( SeekPoint , SeekType ) ;
				} ;

				this.ReadShred.Read = delegate( IntPtr Buffer , IntPtr BlockSize , IntPtr DataNum , IntPtr StreamDataPoint )
				{
					return ( IntPtr )( source.Read( Buffer , ( int )( BlockSize ) , ( int )( DataNum ) ) ) ;
				} ;

				this.ReadShred.Eof = delegate( IntPtr StreamDataPoint )
				{
					return source.Eof() ;
				} ;

				this.ReadShred.IdleCheck = delegate( IntPtr StreamDataPoint )
				{
					return source.IdleCheck() ;
				} ;

				this.ReadShred.Close = delegate( IntPtr StreamDataPoint )
				{
					source.Close() ;
					return 0 ;
				} ;
			}
		}
	}
}
