//
//	ToolLib_Unity.cs
//
//	エディター共通処理 - Unity用のバックエンド
//
//	* Tue May 02 22:54:46 JST 2017 Naoyuki Sawa
//	- 1st リリース。
//	* Sun May 14 23:23:22 JST 2017 Naoyuki Sawa
//	- 描画優先度をテキストとそれ以外で分けました。
//	  詳細は、以下の通りです。
//	- これまでは全て同じ描画優先度で描画しており、DxLib用のバックエンドと同様に、描画した順番に実行されていました。
//	  DxLib+Windowsではそれでも十分な性能が出ていたのですが、Unity+Androidではそれだと極端に処理落ちが発生しました。
//	  そこで、少しでも同じマテリアルがまとまるように、テキストの描画優先度を高くする事にしました。
//	  必ずしもテキストを最前面で書いて良いとは限らないのですが、現在のToolLibの描画内容ではそうして問題有りません。
//	  このように変更した結果、(ToolLib以外の描画にもよりますが)ドローコールが72⇒67に減りました。
//	  大幅な改善ではありませんが、少なくとも現在の所害は無いので、このように変更する事にしました。
//
#if     UNITY_5_3_OR_NEWER
using System;
using UnityEngine;
using static Const;
public static partial class Program {
	//*****************************************************************************
	//	アプリケーション用関数
	//*****************************************************************************
	public static SToolInfo ToolUnity_GetDefault() {
		//SToolInfoから派生した、SToolUnityInfoクラスの、唯一のインスタンスを返す。
		return     SToolUnityInfo.GetDefault();
	}
	//*****************************************************************************
	//	ローカル関数
	//*****************************************************************************
	private class SToolUnityInfo : SToolInfo, ICloneable {
		private static SToolUnityInfo    Default;	//唯一のインスタンス。
		public  static SToolUnityInfo GetDefault() {
			if(Default == null) {	//初回ならば、唯一のインスタンスを作成する。
				Default = new SToolUnityInfo() {
					fnDrawBox			= _fnDrawBox,
					fnDrawStringToHandle		= _fnDrawStringToHandle,
					fnDrawTriangle			= _fnDrawTriangle,
					fnGetColor			= _fnGetColor,
					fnGetDrawScreenSize		= _fnGetDrawScreenSize,
					fnGetDrawStringWidthToHandle	= _fnGetDrawStringWidthToHandle,
					fnGetMouseInput			= _fnGetMouseInput,
					fnGetMousePoint			= _fnGetMousePoint,
					fnSetDrawArea			= _fnSetDrawArea,
					fnSetDrawAreaFull		= _fnSetDrawAreaFull,
					fnSetDrawBlendMode		= _fnSetDrawBlendMode,
					NormalFontHandle		= 1,
					ButtonFontHandle		= 2,
				};
				if((Default.ButtonFontHandle == -1) ||
				   (Default.NormalFontHandle == -1)) { throw new ApplicationException(); }
			}
			return (SToolUnityInfo)Default.Clone();
		}
		//-----------------------------------------------------------------------------
		private const int	BasePriority	= short.MaxValue - 100/*調整可*/;
		private const double	FontScale	= TOOL_FONT_HEIGHT / 14.0/*pSprFntMdaの高さ*/;
		private static int	BlendParam;
		//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
		private static int _fnDrawBox(int x1, int y1, int x2, int y2, uint Color, bool FillFlag) {
			double x = x1, y = y1, w = x2 - x1, h = y2 - y1;
			int rgba = RGBA_SETALPHA((int)Color, BlendParam);
			if(FillFlag) {
				CbkQue_draw_box_fill(pCbkQue, (BasePriority + 0), x, y, w, h, rgba);
			} else {
				CbkQue_draw_box(pCbkQue, (BasePriority + 0), x, y, w, h, rgba);
			}
			return 0;
		}
		private static int _fnDrawStringToHandle(int x, int y, string String, uint Color, int FontHandle/*, uint EdgeColor = 0, bool VerticalFlag = 0*/) {
			int rgba = (FontHandle == 1/*NormalFontHandle*/) ? RGBA_SETALPHA((int)Color, BlendParam) : -1;	//NormalFontHandleでなければ(=ButtonFontHandleならば)、色指定を無視して白で描画する事にした。本来、ButtonFontHandleは縁無しフォントなのだが、2017/05/02現在は縁有りのpSprFntMdaで共用している。pSprFntMdaは縁が黒なので内側も暗い色で書いてしまうと見辛くなるから白固定とする事にした。やっつけの対応ではあるが、実用上はこれでも十分だと思う。
			CbkQue_draw_sprf(pCbkQue, (BasePriority + 1), pSprFntMda, x, y, FontScale, FontScale, 0, 0, 0, rgba, String);
			return 0;
		}
		private static int _fnDrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3, uint Color, bool FillFlag) {
			double[,] xy = new double[,] { { x1, y1 }, { x2, y2 }, { x3, y3 } };
			int rgba = RGBA_SETALPHA((int)Color, BlendParam);
			if(FillFlag) {
				CbkQue_draw_polygon_fill(pCbkQue, (BasePriority + 0), xy, rgba);
			} else {
				CbkQue_draw_polygon(pCbkQue, (BasePriority + 0), xy, rgba);
			}
			return 0;
		}
		private static uint _fnGetColor(int Red, int Green, int Blue) {
			return (uint)RGB_MAKE(Red, Green, Blue);
		}
		private static int _fnGetDrawScreenSize(out int XBuf, out int YBuf) {
			XBuf = DISP_X;
			YBuf = DISP_Y;
			return 0;
		}
		private static int _fnGetDrawStringWidthToHandle(string String, int StrLen, int FontHandle/*, bool VerticalFlag = 0*/) {
			int size_x, size_y;
			if(StrLen != -1) { throw new ApplicationException(); }
			SprFnt_GetSize(pSprFntMda, String, out size_x, out size_y);
			return (int)(size_x * FontScale);
		}
		private static int _fnGetMouseInput() {
			return _Input.mouseStat ? (1<<0)/*MOUSE_INPUT_LEFT*/ : 0;
		}
		private static int _fnGetMousePoint(out int XBuf, out int YBuf) {
			XBuf = _Input.mousePosX;
			YBuf = _Input.mousePosY;
			return 0;
		}
		private static int _fnSetDrawArea(int x1, int y1, int x2, int y2) {
			//※TODO:要検討。Unityにはシザーテストの機能が無い。(?)
			return 0;
		}
		private static int _fnSetDrawAreaFull() {
			//※TODO:要検討。Unityにはシザーテストの機能が無い。(?)
			return 0;
		}
		private static int _fnSetDrawBlendMode(int BlendMode, int BlendParam) {
			switch(BlendMode) {
			default:throw new ApplicationException();
			case 0/*DX_BLENDMODE_NOBLEND*/:
				SToolUnityInfo.BlendParam = 255;
				break;
			case 1/*DX_BLENDMODE_ALPHA*/:
				SToolUnityInfo.BlendParam = clamp(BlendParam, 0, 255);
				break;
			}
			return 0;
		}
		//-----------------------------------------------------------------------------
		//ICloneable
		public object Clone() { return MemberwiseClone(); }
	}
}
#endif//UNITY_5_3_OR_NEWER
