//
//	cliplotr.cs
//
//	抽選表ROM形式
//
//	CLiP - Common Library for P/ECE
//	Copyright (C) 2017 Naoyuki Sawa
//
//	* Wed Mar 01 22:47:42 JST 2017 Naoyuki Sawa
//	- 1st リリース。
//	* Fri Mar 03 22:34:24 JST 2017 Naoyuki Sawa
//	- clipptr_net.csモジュールを追加した事に伴い、ポインタの扱いを大幅に変更しました。
//	  これまでは、配列とインデクスを保持する必要が有りましたが、今後はC言語版と同様に、配列ポインタ一つを保持すれば良くなりました。
//	- 今回は変更量がかなり多かったので、変更前のコードはコメントアウトして残していません。
//	  変更前のコードを参照する場合は、前回のアーカイブを参照して下さい。
//
#define USE_LOT_EQUALLY
//#define USE_LOTROM_LOG
using System;
using System.Collections.Generic;
#if     USE_LOTROM_LOG
using System.IO;
#endif//USE_LOTROM_LOG
namespace org.piece_me {
	public static partial class libclip {
		//*****************************************************************************
		//	構造体定義
		//*****************************************************************************
		private struct ST_LotRom {
			public Int32Ptr				m_TBL_LotTblNo;		//抽選表アドレステーブルへのポインタ	[抽選表番号]⇒TBL_LotTbl[]に対するインデクス
			public Func<object/*fnRndArg*/,int>	m_fnRnd;		//乱数ジェネレータ関数へのポインタ	引数の無い関数も警告無く指定可能とするために、引数を明示しない型定義にしておく。
			public object				m_fnRndArg;		//乱数ジェネレータ関数への引数		引数の無い関数を指定した場合は、引数はダミーとなる。('cdecl呼出規約'なので安全。)
#if     USE_LOTROM_LOG
			public ST_Worksheet			m_wsLog;		//抽選表ログ				null=ログが開始していない事を示す。
#endif//USE_LOTROM_LOG
		}
		//*****************************************************************************
		//	ローカル変数定義
		//*****************************************************************************
		private static ST_LotRom stLotRom;
		//*****************************************************************************
		//	
		//*****************************************************************************
		//抽選表番号に対応する、抽選表へのポインタを取得する。
		private static UInt16Ptr LotRom_GetLotTbl(int LotTblNo) {
			int nLotTblNo = stLotRom.m_TBL_LotTblNo[0];					//(抽選表番号の最大値+1)を取得する。
			UInt16Ptr pLotTbl;
			if((LotTblNo < 1) || (LotTblNo >= nLotTblNo)) { throw new ApplicationException(); }	//抽選表番号が有効範囲である事を確認する。
			pLotTbl = (UInt16Ptr)(stLotRom.m_TBL_LotTblNo + nLotTblNo);			//抽選表データへのポインタを求める。(抽選表アドレステーブルの直後に抽選表データを配置する前提)
			return pLotTbl + stLotRom.m_TBL_LotTblNo[LotTblNo];				//抽選表へのポインタを返す。
		}
		//-----------------------------------------------------------------------------
		//抽選表ROM管理を開始する。
		public static void LotRom_Init(Int32Ptr _TBL_LotTblNo, Func<object/*fnRndArg*/,int> _fnRnd, object _fnRndArg) {
			LotRom_Free();									//既に、抽選表ROM管理が開始していたら、一旦、抽選表ROM管理を終了する。
			stLotRom.m_TBL_LotTblNo	= _TBL_LotTblNo;					//抽選表アドレステーブルへのポインタを格納する。
			stLotRom.m_fnRnd	= _fnRnd;						//乱数ジェネレータ関数へのポインタを格納する。
			stLotRom.m_fnRndArg	= _fnRndArg;						//乱数ジェネレータ関数への引数を格納する。
		}
		//-----------------------------------------------------------------------------
		//抽選表ROM管理を終了する。
		public static void LotRom_Free() {
#if     USE_LOTROM_LOG
			LotRom_EndLog();								//確実に、ログを終了する。
#endif//USE_LOTROM_LOG
			stLotRom = default(ST_LotRom);							//抽選表ROM管理をクリアする。
		}
		//-----------------------------------------------------------------------------
		//抽選表の、指定された抽選列を用いて、抽選を行います。
		public static int LotRom_draw_l(int LotTblNo, params int[] pid) {
			return LotRom_draw_v(LotTblNo, pid);
		}
		public static int LotRom_draw_v(int LotTblNo, IEnumerable<int> pid) {
			int retval = LOT_draw_table_v(LotRom_GetLotTbl(LotTblNo), (ushort)stLotRom.m_fnRnd.Invoke(stLotRom.m_fnRndArg), pid);		//乱数ジェネレータ関数は32bit乱数を返しても良い。当関数が16bit乱数に切り詰める。
#if     USE_LOTROM_LOG
			LotRom_AddLog(LotTblNo, pid, retval);						//抽選表ROM管理が開始していたら、抽選結果をログに記録する。
#endif//USE_LOTROM_LOG
			return retval;
		}
#if     USE_LOT_EQUALLY
		public static int LotRom_draw_equally_l(int LotTblNo, params int[] pid) {
			return LotRom_draw_equally_v(LotTblNo, pid);
		}
		public static int LotRom_draw_equally_v(int LotTblNo, IEnumerable<int> pid) {
			int retval = LOT_draw_table_equally_v(LotRom_GetLotTbl(LotTblNo), (ushort)stLotRom.m_fnRnd.Invoke(stLotRom.m_fnRndArg), pid);	//乱数ジェネレータ関数は32bit乱数を返しても良い。当関数が16bit乱数に切り詰める。
#if     USE_LOTROM_LOG
			LotRom_AddLog(LotTblNo, pid, retval);						//抽選表ROM管理が開始していたら、抽選結果をログに記録する。
#endif//USE_LOTROM_LOG
			return retval;
		}
#endif//USE_LOT_EQUALLY
		//-----------------------------------------------------------------------------
		//抽選表の、指定された抽選列の、指定された当選値の、重み値を取得します。
		public static int LotRom_get_weight_l(int LotTblNo, int hitval_sel, params int[] pid) {
			return LotRom_get_weight_v(LotTblNo, hitval_sel, pid);
		}
		public static int LotRom_get_weight_v(int LotTblNo, int hitval_sel, IEnumerable<int> pid) {
			return LOT_get_table_weight_v(LotRom_GetLotTbl(LotTblNo), hitval_sel, pid);
		}
		//-----------------------------------------------------------------------------
		//抽選表の、列数を取得します。
		public static int LotRom_get_size(int LotTblNo) {
			return LOT_get_table_size(LotRom_GetLotTbl(LotTblNo));
		}
		//-----------------------------------------------------------------------------
		//抽選表の、抽選列のid行数を取得します。
		public static int LotRom_get_id_size(int LotTblNo) {
			return LOT_get_table_id_size(LotRom_GetLotTbl(LotTblNo));
		}
		//-----------------------------------------------------------------------------
		//抽選表の、(i_column)番目の抽選列の、idの組合せを取得します。
		public static int[] LotRom_get_column_id(int LotTblNo, int i_column) {
			return LOT_get_table_column_id(LotRom_GetLotTbl(LotTblNo), i_column);
		}
		//*****************************************************************************
		//	ログ機能
		//*****************************************************************************
#if     USE_LOTROM_LOG
		//ログを開始する。
		public static void LotRom_BeginLog() {
			throw new NotImplementedException();
		}
		//-----------------------------------------------------------------------------
		//ログを出力する。
		public static void LotRom_DumpLog(TextWriter fp) {
			throw new NotImplementedException();
		}
		//-----------------------------------------------------------------------------
		//ログを終了する。
		public static void LotRom_EndLog() {
			throw new NotImplementedException();
		}
		//-----------------------------------------------------------------------------
		//抽選結果をログに記録する。
		private static void LotRom_AddLog(int LotTblNo, IEnumerable<int> pid, int hitval) {
			throw new NotImplementedException();
		}
#endif//USE_LOTROM_LOG
	}
}
