unit RunBatchTool_entry;

interface
uses
  Windows,  SysUtils, Classes, Dialogs,MarbleSDK,MarbleSDKType;

  
function  MCP_PluginEntry (AppHandle : THandle; DllHandle : THandle; Ver : integer; AppPath : PChar; size : integer): integer; cdecl;
function  MCP_GetPluginInfo(sender : TCW_ID; index : integer) : TCW_BOOLEAN; cdecl;
procedure MCP_ReleasePlugin(moduleid : TCW_ID) ; cdecl;

function  MCP_GetToolInfo(sender : TCW_ID; moduleid : TCW_ID) : TCW_BOOLEAN; cdecl;
function  MCP_ToolSwitch(sender : TCW_ID; moduleid : TCW_ID; Enter : TCW_BOOLEAN; doc : PCW_Document; info : PCW_ToolInfo) : TCW_BOOLEAN; cdecl;

exports MCP_PluginEntry, MCP_GetPluginInfo, MCP_ReleasePlugin,
 MCP_GetToolInfo, MCP_ToolSwitch;

implementation

type
  // Tool Option
  TFacetFlowOption = record
    CursorAdjust : TCW_GUI_CheckBox;
    CanFlip : TCW_GUI_CheckBox;
    CanFusion : TCW_GUI_CheckBox;
    CanDivide : TCW_GUI_CheckBox;
  end;

  // Tool Mode State
  TFacetFlowToolData = record
    BeforeEdge : TCW_INT;
  end;

var
  FacetFlowToolData : TFacetFlowToolData;
  FacetFlowOption : TFacetFlowOption;

// ---------------------------------------------------------------------------
// plugin 初期化関数群
// ---------------------------------------------------------------------------


// from: https://stackoverflow.com/questions/9119999/getting-output-from-a-shell-dos-app-into-a-delphi-app
function GetDosOutput(CommandLine: string; Work: string = 'C:\'): string;
var
  SA: TSecurityAttributes;
  SI: TStartupInfo;
  PI: TProcessInformation;
  StdOutPipeRead, StdOutPipeWrite: THandle;
  WasOK: Boolean;
  Buffer: array[0..255] of AnsiChar;
  BytesRead: Cardinal;
  WorkDir: string;
  Handle: Boolean;
begin
  Result := '';
  with SA do begin
    nLength := SizeOf(SA);
    bInheritHandle := True;
    lpSecurityDescriptor := nil;
  end;
  CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SA, 0);
  try
    with SI do
    begin
      FillChar(SI, SizeOf(SI), 0);
      cb := SizeOf(SI);
      dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      wShowWindow := SW_HIDE;
      hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin
      hStdOutput := StdOutPipeWrite;
      hStdError := StdOutPipeWrite;
    end;
    WorkDir := Work;
    Handle := CreateProcess(nil, PChar('cmd.exe /C ' + CommandLine),
                            nil, nil, True, 0, nil,
                            PChar(WorkDir), SI, PI);
    CloseHandle(StdOutPipeWrite);
    if Handle then
      try
        repeat
          WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
          if BytesRead > 0 then
          begin
            Buffer[BytesRead] := #0;
            Result := Result + Buffer;
          end;
        until not WasOK or (BytesRead = 0);
        WaitForSingleObject(PI.hProcess, INFINITE);
      finally
        CloseHandle(PI.hThread);
        CloseHandle(PI.hProcess);
      end;
  finally
    CloseHandle(StdOutPipeRead);
  end;
end;
// from: https://stackoverflow.com/questions/9119999/getting-output-from-a-shell-dos-app-into-a-delphi-app




function  MCP_PluginEntry (AppHandle : THandle; DllHandle : THandle; Ver : integer; AppPath : PChar; size : integer): integer; cdecl;
begin
  if Ver >= $00050600 then
  begin
    result := 1; // このdllに含まれるモジュール数。このサンプルは1つのモジュールを持つので1
  end else begin
    result := 0; // 古いバージョンのMarbleCLAYで動作しないプラグインの場合は0を返す。
                 // モジュール個別で動作の可・不可を切り替えたい場合は、MCP_GetPluginInfoでfalseを返す
  end;
end;

function MCP_GetPluginInfo(sender : TCW_ID; index : integer) : TCW_BOOLEAN; cdecl;
var
  info : TCW_PluginInfo;
begin
  result := CW_TRUE;

  // 各モジュール情報をMarbleCLAYに渡す
  case index of
  0: //0番目のモジュール
    begin
      ZeroMemory(@info, sizeof(info));
      info.Name := PChar('RunBatchTool');
      info.Info := PChar('Run Batch Tool');
      info.AuthorID := 97; // 開発者ID 0=T.Maeda  1以上=各開発者固有の番号
      info.TypeID := CW_TOOL;
      info.ModuleID := TCW_ID(@FacetFlowToolData); // モジュールの識別ID。ここでは各モジュール用の情報格納用構造体のポインタを渡す
    end;
  else
    result := CW_FALSE;
  end;

  if result then CWAPIs.SendData( 0 , sender, CW_PLUGIN_INFO, @info, sizeof(info) );
end;

procedure MCP_ReleasePlugin(moduleid : TCW_ID) ; cdecl;
begin
  if moduleid = TCW_ID(@FacetFlowToolData) then
  begin
  end;
end;

function MCP_GetToolInfo(sender : TCW_ID; moduleid : TCW_ID) : TCW_BOOLEAN; cdecl;
var
  info : TCW_ToolInfo;
begin
  result := CW_TRUE;
  if moduleid = TCW_ID(@FacetFlowToolData) then
  begin
    ZeroMemory(@info, sizeof(info));
    info.IconWidth := 22;
    info.IconHeight := 26;
    info.IconHandle := LoadImage(HInstance, 'RunBatchTool_tool', IMAGE_BITMAP,0,0, LR_DEFAULTSIZE); // アイコン画像をリソースから読み出す b5.5
    info.IconFileName := '';// アイコン画像をファイルから読み出す場合 'FacetFlowTool.bmp'; // アイコンファイル
    info.IconIndex := 0; // アイコン画像に複数のアイコンを含んでいる場合は、そのインデックスを指定する
    info.Kind := CW_TOOL_IMAGE;
    info.ToolFilter := 0;// CWBIT_FILTER_FACE or CWBIT_FILTER_REVFACE or CWBIT_FILTER_EDGE or CWBIT_FILTER_VERTEX;
    info.DraggingFilter := 0;
    info.Attr := 0;// CWBIT_TOOLATTR_CANREGIST_QUICKR;
    // info.CursorHandle := LoadImage(HInstance, 'RunBatchTool_cur', IMAGE_CURSOR,0,0, LR_DEFAULTSIZE);
  end else begin
    result := CW_FALSE;
  end;

  if result then CWAPIs.SendData( moduleid, sender, CW_MODULE_INFO, @info, sizeof(info) );
end;


// ---------------------------------------------------------------------------
// GUIイベント
// ---------------------------------------------------------------------------

// ---------------------------------------------------------------------------
// plugin Tool呼び出し 入り口
// ---------------------------------------------------------------------------

function MCP_ToolSwitch(sender : TCW_ID; moduleid : TCW_ID; Enter : TCW_BOOLEAN; doc : PCW_Document; info : PCW_ToolInfo) : TCW_BOOLEAN; cdecl;
var
  temp,temp1,temp2,temp3,temp4 : string;
begin

	result := CW_FALSE;


	info^.ModeCount := 0;
  if (moduleid = TCW_ID(@FacetFlowToolData)) and (Enter = CW_TRUE) then
  begin
  
  
			result := CW_TRUE;

			temp4 := 'C:\\Program Files\\MarbleCLAY\\Plugin\\runbatch.bat';
				//ShowMessage(temp4);		
				
				if FileExists(temp4)  then
				begin
						temp2 := 'call cmd /C "' +  temp4 + '"  & exit';
						// ShowMessage(temp2);	
						temp2 := GetDosOutput(temp2);
						ShowMessage(temp2);			
				
				end else begin
						temp4 := 'C:\\MarbleCLAY\\plugin\\runbatch.bat';
						
						// ShowMessage(temp4);		
						
						if FileExists(temp4) then
						begin
								temp2 := 'call cmd /C "' +  temp4 + '"  & exit';
							//	ShowMessage(temp2);	
								temp2 := GetDosOutput(temp2);
								ShowMessage(temp2);					
						end;
				end;				
	

	// result := false;
     //result := SwitchFacetFlowTool( doc, toolinfo );
  end;


end;


function ObjectAttrInteger( obj : PCW_MeshObject; name : string; def : integer) : Integer;
var
  pval_buff : PChar;
  buffsize : integer;
begin
  result := def;

  // beta5.5
  buffsize := CWAPIs.GetObjectAttr( obj, PChar(name), nil, 0 );
  if buffsize > 0 then
  begin
    try
      GetMem(pval_buff, buffsize);
      try

        if CWAPIs.GetObjectAttr( obj, PChar(name), pval_buff, buffsize ) > 0 then
        begin
          result := StrToInt(PChar(pval_buff));
        end;

      finally
        FreeMem(pval_buff);
      end;
    except
      on E:EOutOfMemory do result := def;
    end;
  end;

end;

function ViewAttrInteger( view : PCW_View; name : string; def : integer) : Integer;
var
  pval_buff : PChar;
  buffsize : integer;
begin
  result := def;

  // beta5.5
  buffsize := CWAPIs.GetViewAttr( view, PChar(name), nil, 0 );
  if buffsize > 0 then
  begin
    try
      GetMem(pval_buff, buffsize);
      try

        if CWAPIs.GetViewAttr( view, PChar(name), pval_buff, buffsize ) > 0 then
        begin
          result := StrToInt(PChar(pval_buff));
        end;

      finally
        FreeMem(pval_buff);
      end;
    except
      on E:EOutOfMemory do result := def;
    end;
  end;

end;




end.
