/**
 * 擬似コードによるマニュアル
 */

/**
 * Window拡張
 */
class Window {
	/**
	 * ウィンドウの最大化
	 * 最大化ボタンを押した動作と同等
	 * サイズ固定ウィンドウでは機能しない
	 */
	function maximize();

	/**
	 * ウィンドウ最大化ボタンの有無
	 */
    property maximizeBox;

	/**
	 * ウィンドウ最小化ボタンの有無
	 */
    property minimizeBox;

	/**
	 * ウィンドウが最大化かどうか取得
	 * setterも一応あるが使わないことを推奨
	 */
	property maximized {
		getter;
		setter(v) { if (maximized != v) { if (v) maximize(); else showRestore(); } }
	}

	/**
	 * ウィンドウの最小化（mainWindowではタスクバー収納，それ以外は画面左下に最小化）
	 * 最小化ボタンを押した動作と同等
	 */
	function minimize();

	/**
	 * ウィンドウが最小化かどうか取得
	 */
	property minimized {
		getter;
		setter(v) { if (minimized != v) { if (v) minimize(); else showRestore(); } }
	}

	/**
	 * ウィンドウ最大化・最小化の復帰
	 */
	function showRestore();

	/**
	 * ウィンドウのタイトルバーアイコンを再設定する
	 *  ※ Vista でフルスクリーンから復帰するとアイコンが消える問題（吉里吉里v2.30で確認）の消極的対処メソッド
	 */
	function resetWindowIcon();

	/**
	 * ウィンドウのタイトルバーアイコンを変更する
	 * @param file アイコンファイルまたはvoid (voidか""で初期状態にリセット）
	 * @param withapp アプリケーションウィンドウのアイコンも一緒に変更するかどうか
	 * ※ アーカイブ内のファイル指定は不可，exeやDLLを指定した場合は一番最初のアイコンが設定される
	 */
	function setWindowIcon(file, withapp);

	/**
	 * クライアント・ウィンドウ領域，非最大化通常表示の領域の取得
	 * @return %[ x, y, w, h ] または void(取得失敗時)
	 * ※ innerSunken枠分はクライアント領域に含まれるので注意
	 */
	function getClientRect(); //< クライアント領域
	function getWindowRect(); //< ウィンドウ領域
	function getNormalRect(nofix=false); //< 非最大化通常表示領域(@param nofix true:ワークエリア補正を行わない)

	/**
	 * ウィンドウの Zオーダーを変更する
	 * @param win Windowオブジェクトまたは規定文字列または数値
	 *            Windowオブジェクトなら，そのウィンドウの後ろに置かれる
	 *            文字列の場合，"bottom" "notopmost" "top" "topmost" のいずれか（HWND_*相当）cf. SetWindowPos API
	 *            数値の場合，ウィンドウハンドルと見なすか，HWND_* マクロの値を直指定する
	 *						#define HWND_TOP        ((HWND)0)
	 *						#define HWND_BOTTOM     ((HWND)1)
	 *						#define HWND_TOPMOST    ((HWND)-1)
	 *						#define HWND_NOTOPMOST  ((HWND)-2)
	 * @param activate アクティブ状態にするかどうかのフラグ
	 *                 trueにしてもアプリケーション自体はアクティブになりません（タスクバーの点滅などおこりません）
	 */
	function bringTo(win = "top", activate = false);

	/// alias method
	function sendToBack() { bringTo("bottom"); }


	/**
	 * 拡張イベントを有効にする
	 * このウィンドウのインスタンスについて
	 * 説明に「■拡張イベント：」と記述されているコールバックが有効になる
	 *
	 * ただし、下記のコールバックについては
	 * この関数を実行した時点でインスタンスに存在しない場合には発生しないので注意
	 * （ない場合は後からインスタンスに関数を追加しても呼ばれない）
	 *  onMoving      移動中
	 *  onMove        移動
	 *  onResizing    リサイズ中
	 *  onNcMouseMove NonClient領域でのマウス移動
	 */
	function registerExEvent();

	/**
	 * ■拡張イベント：最大化を許可するかどうか確認
	 * @return true を返すと最大化を許可しない
	 */
	function onMaximizeQuery();

	/**
	 * ■拡張イベント：ウィンドウ最大化
	 * 呼ばれた時点でウィンドウサイズは既に最大化されている
	 */
	function onMaximize();

	/**
	 * ■拡張イベント：ウィンドウ最小化
	 * フルスクリーン中にAlt+Tabなどで別のアプリを選んだ場合や，mainWindow以外が最小化されたときに呼ばれる
	 * タスクバーに収納された場合は onHide イベントが呼ばれるので注意
	 */
	function onMinimize();

	/**
	 * ■拡張イベント：ウィンドウ表示
	 * タスクバーから復帰したときなどに呼ばれる
	 */
	function onShow();

	/**
	 * ■拡張イベント：ウィンドウ非表示
	 * タスクバーに収納された時などに呼ばれる
	 */
	function onHide();

	/**
	 * ■拡張イベント：リサイズ・移動開始通知/終了
	 * フレームやタイトルバーをドラッグ開始した時やAlt+SpaceでSやMを選んだ時（開始通知），
	 * および移動やリサイズが終了した時（終了通知）にそれぞれ呼ばれる
	 * onMovingやonResizing中に元のウィンドウ位置やサイズを参照したい時はここで保存しておくとよい
	 * リサイズか移動かは WM_ENTERSIZEMOVE/WM_EXITSIZEMOVE の都合で判定不可
	 */
	function onMoveSizeBegin(); //< 開始通知
	function onMoveSizeEnd();   //< 終了通知

	/**
	 * ■拡張イベント：ウィンドウ移動中
	 * @param rect %[ x, y, w, h ] ウィンドウ座標
	 * 
	 * ※Windowsでウィンドウ内容を表示したまま移動する設定（移動枠表示なし）の場合，すぐにonMoveが呼ばれる
	 */
	function onMoving(rect); //< registerExEvent()後の追加は無効（詳細はregisterExEventの説明を参照）

	/**
	 * ■拡張イベント：ウィンドウ移動（完了）
	 * @param x,y クライアント領域左上のスクリーン座標
	 *            ※ innerSunken枠分はクライアント領域に含まれるので注意
	 */
	function onMove(x, y); //< registerExEvent()後の追加は無効（詳細はregisterExEventの説明を参照）

	/**
	 * ■拡張イベント：サイズ変更中
	 * @param rect %[ x, y, w, h, type ] 変更中サイズ（ウィンドウ座標）
	 * @param rect.type ウィンドウのどこをつかんでサイズを変更しているか 1〜8
	 *                  +1:左側, +2:右側, +3:上側, +6:下側  の組み合わせ（3進数的表現）
	 *                         4 3 5
	 *                  配置： 1   3
	 *                         7 6 8
	 * @return true を返すと rect の変更を反映（位置・サイズを強制指定）
	 *         この場合，つかんだ位置(rect.type)に応じてうまく書き換え内容を調整しないと
	 *         サイズ変更中にウィンドウが動いてしまうことがあるので注意（⇒forceResizeRect()参照）
	 * 
	 * ※Windowsでウィンドウ内容を表示したままリサイズする設定（サイズ枠表示なし）の場合，すぐにonResizeが呼ばれる
	 */
	function onResizing(rect); //< registerExEvent()後の追加は無効（詳細はregisterExEventの説明を参照）

@if (0)
	/* （※これはプラグインで拡張される関数ではありません！）
	 * onResizingでサイズを固定させるサンプル
	 * @param rect onResizingに渡された引数
	 * @param w, h 固定したいサイズ(voidなら変更しない)
	 * @return 変更されたらtrue
	 */
	function forceResizeRect(rect, w, h) {
		with (rect) {
			w = .w if (w === void);
			h = .h if (h === void);
			var x = (.type   % 3 == 1) ? (.x+.w) - w : .x;
			var y = (.type\3 % 3 == 1) ? (.y+.h) - h : .y;
			if (.x == x && .y == y && .w == w && .h == h) return false;
			.x = x;
			.y = y;
			.w = w;
			.h = h;
		}
		return true;
	}
@endif

	/**
	 * ■拡張イベント：ディスプレイ構成の変更通知
	 * 解像度や色数、マルチモニタの構成（位置変更も含む）が変更されたときに呼ばれる
	 */
	function onDisplayChanged();

	/**
	 * ■拡張イベント：メニュー処理の開始・終了通知
	 * ウィンドウのメニュー処理（クリックやF10を押した場合など）の開始と終了の通知イベント
	 * WM_ENTERMENULOOP / WM_EXITMENULOOP 通知のコールバック
	 *
	 * ※フルスクリーンにした場合のメニューではこのイベントは発生しないので注意！
	 */
	function onEnterMenuLoop(); //< メニュー処理開始
	function onExitMenuLoop();  //< メニュー処理終了

	/**
	 * ■拡張イベント：スクリーンセーバー開始通知，モニタパワー変更通知
	 * @param mode -1/1/2
	 * @return true を返すと制御抑制
	 */
	function onScreenSave();
	function onMonitorPower(mode);

	/**
	 * リサイズの抑制
	 * setter は registerExEvent() で拡張イベントを登録していないと例外が発生する
	 * true に設定すると，borderStyle == bsSizeable の場合でも
	 * ・ウィンドウ淵のサイズ変更カーソルが出なくなりサイズが変更できなくなる
	 * ・システムメニュー(Alt+Space)のサイズ変更がグレーになり選択できなくなる
	 * 最大化など他の方法でのサイズ変更は有効(onResizeも飛ぶ)
	 */
	property disableResize { getter; setter; }

	/**
	 * 移動の抑制
	 * SYSTEMCOMMANDのSC_MOVEを抑制する
	 */
	property disableMove   { getter; setter; }

	/**
	 * ■拡張イベント：アクティブ状態変更通知
	 * @param active 0:非アクティブ化 1:マウスクリック以外でアクティブ化 2:マウスクリックでアクティブ化
	 * @param minimize 0:ウィンドウは最小化されていない それ以外:最小化されている
	 *
	 * ※Window.onActivate や Window.onDeactivate と違うのは、（これは拡張イベント全般に言えることだが）
	 * System.eventDisabled == true でもイベントコールバックが飛んでくるという点
	 *
	 * 例えば System.onDeactivate 時に System.eventDisabled=true（こうすると System.onActivateは
	 * 飛んでこない）にして，このイベント通知で復帰させると「非アクティブ時に動作停止」といった機能を
	 * 追加できるかもしれない（ただしこれはイベントを配信停止するだけなので，前との時間差を見るような
	 * タイマーを使ったアプリではあまり意味が無い）
	 * なお，System.eventDisabled=true 時は画面更新すら走らないので，他のウィンドウを上にするなどして
	 * WM_PAINT が発生すると画面が崩れる問題がある（後述の OverlayBitmap を使うなどする）
	 */
	function onActivateChanged(active, minimize);

	/**
	 * オーバーレイビットマップを表示・消去する
	 * @param layer ビットマップ画像にコピーするレイヤ（void or省略時はオーバーレイ消去）
	 *
	 * 指定画像でクライアント領域に子ウィンドウ（吉里吉里のではなくWindowsのそれ）をかぶせる
	 * ・拡張イベントが有効でないと例外が発生する
	 * ・オーバーレイ表示中は吉里吉里のレイヤ側にマウス系のメッセージが一切行かない
	 * ・実質的に System.eventDisabled=true の時専用
	 * ・TVP_WM_DETACH で自動消去される
	 *
	 */
	function setOverlayBitmap(layer)

	/**
	 * ■拡張イベント：非クライアントエリアマウスイベント
	 * @param x, y マウス座標
	 * @param ht 領域の種類（NCHITTEST定数）
	 * @param btn マウスボタン（mbLeft, mbRight, mbMiddle）
	 */
	function onNcMouseMove(x, y, ht); //< registerExEvent()後の追加は無効（詳細はregisterExEventの説明を参照）
	function onNcMouseUp(  x, y, btn, ht);
	function onNcMouseDown(x, y, btn, ht);
	function onNcMouseLeave();

	/**
	 * 非クライアントエリア調査
	 * @param x, y スクリーン座標
	 */
	function ncHitTest(x, y);

	/// NCHITTEST定数
	/* static */ var nchtError;					//< HTERROR
	/* static */ var nchtTransparent;			//< HTTRANSPARENT
	/* static */ var nchtNoWhere;				//< HTNOWHERE
	/* static */ var nchtClient;				//< HTCLIENT
	/* static */ var nchtCaption;				//< HTCAPTION
	/* static */ var nchtSysMenu;				//< HTSYSMENU
	/* static */ var nchtSize;					//< HTSIZE
	/* static */ var nchtGrowBox;				//< HTGROWBOX
	/* static */ var nchtMenu;					//< HTMENU
	/* static */ var nchtHScroll;				//< HTHSCROLL
	/* static */ var nchtVScroll;				//< HTVSCROLL
	/* static */ var nchtMinButton;				//< HTMINBUTTON
	/* static */ var nchtReduce;				//< HTREDUCE
	/* static */ var nchtMaxButton;				//< HTMAXBUTTON
	/* static */ var nchtZoom;					//< HTZOOM
	/* static */ var nchtLeft;					//< HTLEFT
	/* static */ var nchtRight;					//< HTRIGHT
	/* static */ var nchtTop;					//< HTTOP
	/* static */ var nchtTopLeft;				//< HTTOPLEFT
	/* static */ var nchtTopRight;				//< HTTOPRIGHT
	/* static */ var nchtBottom;				//< HTBOTTOM
	/* static */ var nchtBottomLeft;			//< HTBOTTOMLEFT
	/* static */ var nchtBottomRight;			//< HTBOTTOMRIGHT
	/* static */ var nchtBorder;				//< HTBORDER

	/**
	 * システムメニューに追加
	 * setter は registerExEvent() で拡張イベントを登録していないと例外が発生する
	 * MenuItemまたは辞書の配列を指定する
	 * このメニューが選択されると onExSystemMenuSelected(選択されたオブジェクト) コールバックが発生
	 */
	property exSystemMenu { getter; setter; }

	/**
	 * 追加システムメニューを再生成する(吉里吉里Z向け)
	 * 吉里吉里ZではborderStyleを変更でシステムメニューがリセットされるため
	 * プロパティ変更後にこのメソッドを呼ぶこと
	 * ※WM_INITMENUPOPUPで検知して再生成するとメニューの表示位置がズレてしまう問題があるため
	 */
	function resetExSystemMenu();


	// 以下特殊用途
	property enableNCMouseEvent { getter; setter; } //< WM_SETCURSORのコールバックonNonCapMouseEventを有効にする（デフォルト：false）
	function onNonCapMouseEvent(ht, ev); //< WM_SETCURSORコールバック：ht=LOWORD(LParam), ev=HIWORD(LParam)
	function focusMenuByKey(key); //< SC_KEYMENUを送る
	function onStartKeyMenu(key); //< SC_KEYMENU通知コールバック
	function onAccelKeyMenu(key,st); //< WM_MENUCHAR通知コールバック
	function setMessageHook(on, ev); //< メッセージフックを設定(on:有効, ev:イベント番号またはイベント名文字：省略時全部）
	function onWindowsMessageHook(msg,wp,lp); //< setMessageHookで指定したイベント発生時のコールバック
	/*static*/function getNotificationNum(name); //< WM_XXXイベント番号を取得（WM_は除いて渡す）
	/*static*/function getNotificationName(num); //< イベント番号からWM_XXXを取得（WM_を除いて返る）
}

/**
 * MenuItem拡張
 */
class MenuItem {
	/**
	 * メニューバーの右端分け表示
	 *  true ならその Item 以降は右端に寄せられる
	 * ※ Window.menu 直下で visible でない正しく動作しない
	 */
	property rightJustify { getter; setter };

	/**
	 * アイコンの表示
	 * 設定内容は MenuItem.bi* 定数を使用するか，レイヤオブジェクトを渡す
	 * ※ 値を設定する時点で Window.menu の子で visible でないと機能しないので注意
	 *    また，プルダウンメニューは，Window.registerExEvent()をして拡張イベントを登録しないと表示されないので注意
	 */
//	property bmpItem      { getter; setter }; //< 文字列位置アイコン（チェック／未チェックアイコンの同時指定不可？）
	property bmpChecked   { getter; setter }; //< チェック時アイコン (0でデフォルト)
	property bmpUnchecked { getter; setter }; //< 未チェック時アイコン (0でデフォルト)

	/// bmpItem 定数
	/* static */ var biSystem;					//< HBMMENU_SYSTEM
	/* static */ var biRestore;					//< HBMMENU_MBAR_RESTORE
	/* static */ var biMinimize;				//< HBMMENU_MBAR_MINIMIZE
	/* static */ var biClose;					//< HBMMENU_MBAR_CLOSE
	/* static */ var biCloseDisabled;			//< HBMMENU_MBAR_CLOSE_D
	/* static */ var biMinimizeDisabled;		//< HBMMENU_MBAR_MINIMIZE_D
	/* static */ var biPopupClose;				//< HBMMENU_POPUP_CLOSE
	/* static */ var biPopupRestore;			//< HBMMENU_POPUP_RESTORE
	/* static */ var biPopupMaximize;			//< HBMMENU_POPUP_MAXIMIZE
	/* static */ var biPopupMinimize;			//< HBMMENU_POPUP_MINIMIZE

	/**
	 * ポップアップ表示
	 * @param flags
	 * @param x, y  表示位置（スクリーン座標，省略時マウスカーソル位置）
	 * @param hwnd オーナウィンドウ（省略時インスタンス所属ウィンドウ）
	 * @param rect オーバーラップ禁止範囲（%[ x, y, w, h ]，省略時禁止範囲無し）
	 * @param menulist メニュー一覧配列（MenuItemのインスタンスである必要はなく，辞書を並べても良い）
	 * @return 選択されたオブジェクト
	 * 
	 * MenuItem.popupのようにウィンドウメニュー所属である必要はなく，また一覧も辞書の配列を渡すなどができる
	 * この関数によるポップアップでのbmp*プロパティによるアイコン表示はされないので注意
	 */
	function popupEx(flags, x=cursorX, y=cursorY, hwnd=this.root.window, rect, menulist=this.children);
}

/**
 * Debug.console拡張
 */
class Console {
	function restoreMaxmimize(); //< ウィンドウ最大化の復帰（最大化のまま終了すると次回サイズが狂う問題解決用）
	function maxmimize();        //< ウィンドウを最大化
	function getRect();          //< 座標・サイズの取得
	function setPos(x, y, w, h); //< 座標・サイズの設定
	function getPlacement();     //< WindowPlacementの取得
	function setPlacement(dict); //< WindowPlacementの設定
	//※ 起動後１度はvisible=trueしてウィンドウを生成しないと失敗する
	function bringAfter(win);    //< 優先順位の変更
}

/**
 * Pad拡張
 */
class Pad {
	/**
	 * 拡張イベントを有効にする（登録失敗で例外が発生）
	 * 拡張イベントとして以下が発生：
	 *  onClose  閉じるボタンが押された
	 *
	 * ※borderStyleなどの変更によりウィンドウが作り直されるとイベントが発生しなくなるので注意
	 *   ⇒その場合は再度registerExEvent()を呼ぶ
	 */
	function registerExEvent();
}

/**
 * System拡張
 */
class System
{
	/**
	 * モニタの情報一覧を取得
	 * @param x,y,w,h 範囲枠指定。交わるモニタのみを返す。全省略で全てのモニタを返す。
	 * @return [ %[ name, primary, monitor:%[ x, y, w, h ], work:%[ x,y,w,h ], intersect:%[ x,y,w,h ] ], ... ];
	 *         name:      モニタの名前('\\.\DISPLAY?' 等)
	 *         primary:   プライマリモニタかどうか
	 *         monitor:   モニタの範囲辞書
	 *         work:      モニタのワークエリア範囲(ウィンドウを最大化したときなどの表示範囲)
	 *         intersect: 指定範囲と交わる領域(指定しなかった場合は monitor と同じ)
	 */
	function getDisplayMonitors();            //< 全てのモニタを列挙する
	function getDisplayMonitors(x, y, w, h);  //< 指定範囲に交わるモニタのみ列挙する

	/**
	 * モニタ情報を取得
	 * @param near     trueなら対象モニタが無かった場合に最も近いモニタの情報を返す
	 * @param x,y      座標指定
	 * @param x,y,w,h  範囲指定
	 * @param window   ウィンドウ指定（Window オブジェクトを渡す）
	 * @return %[ name, primary, monitor:%[ x, y, w, h ], work:%[ x, y, w, h ] ];
	 *         モニタの情報。辞書内容は getDisplayMonitors と同じ (ただし intersect 情報は無い)。
	 *         near=false 時でモニタが無い場合は void を返す。
	 */
	function getMonitorInfo();                 //< プライマリモニタを返す
	function getMonitorInfo(near, x, y);       //< 指定座標の位置のモニタを返す
	function getMonitorInfo(near, x, y, w, h); //< 指定座標の範囲にもっとも多く交わるモニタを返す
	function getMonitorInfo(near, window);     //< 指定ウィンドウの範囲にもっとも多く交わるモニタを返す

	/**
	 * マウスカーソルのスクリーン座標を設定・取得
	 * @param  set時：   x, y スクリーン座標
	 * @return get時：%[ x, y ] または void(取得失敗時)
	 */
	function setCursorPos(x, y);
	function getCursorPos();

	/**
	 * システムメトリクス情報を取得
	 * @param index SM_* の「*」部分の文字列（ただし大文字小文字は無関係）
	 * @return メトリクス値（indexにより内容が異なる）
	 *
	 * 詳細は GetSystemMetrics() API のマニュアルを参照
	 * SW_ARRANGE は ARW_* の定義がないので直接数値指定で比較すること
	 */
	function getSystemMetrics(index);

	/**
	 * システムのダブルクリック許容時間を取得
	 * @return 時間(ms) 既定値は500ms
	 *
	 * 詳細は GetDoubleClickTime() API のマニュアルを参照
	 * ダブルクリックの許容移動範囲はgetSystemMetricsのCXDOUBLECLK/CYDOUBLECLKで取得可能
	 * Layer.onDoubleClickを使わずにソフトウェアで擬似的にダブルクリック判定を行う場合に使用（時間決め打ちでも問題ないけど一応…）
	 */
	function getDoubleClickTime();

	/**
	 * 環境変数を取得
	 * @param name 環境変数名
	 * @return 環境変数値（未定義の場合はvoid）
	 */
	function readEnvValue(name);

	/**
	 * 文字列内の「%〜%」を環境変数で展開
	 * @param text 展開する文字列
	 * @return 展開後文字列
	 */
	function expandEnvString(text);

	/**
	 * タスクバーやALT+TABなどで表示されるアプリケーションアイコンを変更する
	 * @param file アイコンファイルまたはvoid (voidか""で初期状態にリセット）
	 * ※ アーカイブ内のファイル指定は不可，exeやDLLを指定した場合は一番最初のアイコンが設定される
	 */
	function setApplicationIcon(file);

	/**
	 * Vista以降のタスクバーやAlt+TABでのサムネイル表示を強制的にアプリケーションアイコン表示にする
	 * @param iconic trueならサムネイルの代わりにアイコンを表示する／falseなら設定解除
	 * @return 成功したかどうか（XP以前では常に失敗）
	 * ※ アプリケーションウィンドウに DWMWA_FORCE_ICONIC_REPRESENTATION が設定される
	 */
	function setIconicPreview(iconic);

	/**
	 * TVPBreathe, TVPGetBreathing のラッパ
	 */
	function breathe();
	function isBreathing();
}

/**
 * Scripts拡張
 */
class Scripts
{
	/**
	 * Scripts.evalのエラーログ出力抑制
	 * @param enabled 出力許可
	 * @return 元の値
	 *
	 * enabled に false を設定すると Scripts.eval の評価処理を
	 * TVPExecuteExpression 経由で行うようになり，例外発生時にログが出力されない
	 * 吉里吉里のバージョンアップに伴い仕様が変わる可能性があるので注意のこと
	 */
	function setEvalErrorLog(enabled);
}
