//API转换工具
import win.ui;
import fonts.fontAwesome;
/*DSG{{*/
var winform = win.form(cls="AFORM";text="API转换工具";left=0;top=0;right=845;bottom=513;parent=...;style=0)
winform.add(
btnGuid2Aardio={cls="button";text='\uF040   C/C++ GUID定义转换为 aardio 格式';left=382;top=2;right=653;bottom=34;dl=1;dt=1;font=LOGFONT(h=14;name='FontAwesome');z=3};
btnStruct2Aardio={cls="button";text='\uF1C9  C/C++ 类型名、结构体、函数声明转换为 aardio 格式';left=14;top=2;right=375;bottom=34;dl=1;dt=1;font=LOGFONT(h=14;name='FontAwesome');z=1};
txtCode={cls="richedit";text="请输入要转换的代码......";left=10;top=35;right=835;bottom=501;db=1;dl=1;dr=1;dt=1;edge=1;hscroll=1;multiline=1;tabstop=1;vscroll=1;z=2}
)
/*}}*/

import win.clip;
import win.ui.menu;
winform.popmenu = win.ui.popmenu(winform);//创建弹出菜单
winform.popmenu.add('复制全部',function(id){ win.clip.write(winform.txtCode.text)})
winform.popmenu.add('粘贴全部',function(id){ winform.txtCode.text = win.clip.read() });
 
winform.txtCode.wndproc = function(hwnd,message,wParam,lParam){
	if( message= 0x205/*_WM_RBUTTONUP*/ ) {  
		winform.popmenu.popup( win.getMessagePos(lParam) );//弹出菜单
	} 
} 

winform.txtCode.color = 0x999999
winform.txtCode.oncommand = function(id,event){
    if(event==0x200/*_EN_KILLFOCUS*/){
        if( winform.txtCode.text == "" ) {
        	winform.txtCode.color = 0x999999;
        	winform.txtCode.text = "请输入要转换的代码......";
       	};
    }
    elseif(event==0x100/*_EN_SETFOCUS*/){
        if( winform.txtCode.text = "请输入要转换的代码......" ) {
        	winform.txtCode.color = 0;
        	winform.txtCode.text = "";
        };
    } 
}

import string.list;
winform.btnStruct2Aardio.oncommand = function(id,event) { 

var byval=/*
LONG=int
CHAR=BYTE
CCHAR=BYTE
PSZ=string
PCNZWCH=ustring
PCHAR=string
PSTR=string
LPSTR=string
NPSTR=string
PCSTR=string
LPCSTR=string
WCHAR=WORD
PWCH=string
PWCHAR=ustring
PWSTR=ustring
LPWSTR=ustring
NWPSTR=ustring
PCWCH=ustring
LPCWCH=ustring
PCWSTR=ustring
LPCWSTR=ustring
TCHAR=word
PTCHAR=ustring
PTCH=string
LPTCH=string
PTSTR=ustring
LPTSTR=ustring
PCTSTR=ustring
LPCTSTR=ustring
UCHAR=BYTE
PUCHAR=string
BSTR=ptr
OLECHAR=word
LPOLESTR=ustring
LPCOLESTR=ustring
BYTE=BYTE
PBYTE=ptr
LPBYTE=ptr
TBYTE=word
PTBYTE=ustring
BOOL=bool
BOOLEAN=BYTE
SHORT=word
USHORT=WORD
INT32=int
INT64=long
INT_PTR=addr
UINT32=INT
UINT64=LONG
UINT_PTR=INT
UINT=INT
LONG32=int
LONG64=long
LONGLONG=long
__int64=long
LONG_PTR=addr
ULONG=INT
ULONG32=INT
ULONG64=LONG
ULONGLONG=LONG
ULONG_PTR=ADDR
DWORD32=INT
DWORD64=long
DWORD_PTR=INT
PDWORD=INT
FLOAT=float
GLOBALHANDLE=pointer
HDC=ptr
HBITMAP=ptr
HBRUSH=ptr
HICON=ptr
HCURSOR=ptr
HPALETTE=ptr
HPEN=ptr
HCONV=ptr
HACCEL=ptr
HCONVLIST=ptr
HDDEDATA=ptr
HDESK=ptr
HDLG=pointer
HDROP=ptr
HDWP=ptr
HENHMETAFILE=ptr
HFILE=int
HFONT=ptr
HGDIOBJ=ptr
HGLOBAL=ptr
HHOOK=ptr
HIMAGELIST=pointer
HIMC=pointer
HINSTANCE=ptr
HKEY=ptr
HKL=ptr
HLOCAL=ptr
HMEMU=pointer
HMETAFILE=ptr
HMIDIIN=pointer
HMIDIOUT=pointer
HMMIO=pointer
HMODULE=ptr
HMONITOR=ptr
HRGN=ptr
HRSRC=ptr
HSZ=ptr
HWAVEIN=pointer
HWAVEOUT=pointer
HWINSTA=ptr
HWND=HWND
LOCALHANDLE=pointer
SC_HANDLE=ptr
SC_LOCK=ptr
SERVICE_STATUS_HANDLE=ptr
MFENUMPROC=pointer
ENUMFENUMPROC=pointer
ENUMRESLANGPROC=pointer
ENUMRESNAMEPROC=pointer
ENUMRESTYPEPROC=pointer
FONTENUMPROC=pointer
GOBJENUMPROC=pointer
HOOKPROC=pointer
LPCCHOOKPROC=pointer
LPCFHOOKPROC=pointer
LPFRHOOKPROC=pointer
LPOFNHOOKPROC=pointer
LPPRINTHOOKPROC=pointer
LPSETUPHOOKPROC=pointer
FARPROC=pointer
DLGPROC=pointer
LINEDDAPROC=pointer
LOHANDLER_FUNCTION=pointer
PROPENUMPROC=pointer
PFNCALLBACK=pointer
PHANDLER_ROUTINE=pointer
TIMERPROC=pointer
WNDENUMPROC=pointer
WNDPRO=pointer
YIELDPROC=pointer
ATOM=WORD
LPRESULT=int
LRESULT=addr
COLORREF=INT
WPARAM=ADDR
LPARAM=addr
CRITICAL_SECTION=struct
LANGID=WORD
LCID=INT
LCTYPE=INT
MCIDEVICEID=INT
MMRESULT=INT
PCRITICAL_SECTION=pointer
PHKEY=pointer
POINTER_32=int
POINTER_64=long
REGSAM=INT
SIZE_T=ADDR
SSIZE_T=addr
UNSIGNED=INT
LUID=struct
VOID=void
PVOID=ptr
LPVOID=ptr
LPCVOID=pointer
DWORD=INT
DWORDLONG=INT
HALF_PTR=ptr
HANDLE=ptr
HGIDOBJ=ptr
HMENU=ptr
HRESULT=int
LARGE_INTEGER=long
LGRPID=INT
POINTER_SIGNED=ptr
POINTER_UNSIGNED=ADDR
PUHALF_PTR=ptr
UHALF_PTR=ptr
ULARGE_INTEGER=LONG
USN=long
WORD=WORD
*/

var byref=/*
LPWORD=WORD
LPBOOL=bool
LPCOLORREF=INT
LPCRECT=struct
LPCRECTL=struct
PLUID=struct
PLCID=INT
LPCOLORREF=INT
LPCRITICAL_SECTION=struct
LPHWAVEIN=pointer
LPHWAVEOUT=pointer
PFLOAT=float
HANDLE=pointer
PHANDLE=ptr
SPHANDLE=pointer
LPHANDLE=ptr
PLONG=LONG
LPLONG=long
PULONG=INT
PULONGLONG=LONG
PWORD=WORD
LPWORD=WORD
LPDWORD=INT
PUINT=INT
PINT=int
LPINT=int
PLONGLONG=long
PBOOL=bool
LPBOOL=int
PSHORT=word
PUSHORT=WORD
PBOOLEAN=BYTE
PDWORD=INT
PDWORDLONG=LONG
PDWORD_PTR=INT
PDWORD32=INT
PDWORD64=long
PHALF_PTR=ptr
PHKEY=ptr
PINT_PTR=INT_PTR
PINT32=int
PINT64=long
PLONG_PTR=addr
PLONG32=long
PLONG64=long
PSIZE_T=ADDR
PSSIZE_T=addr
PUCHAR=BYTE
PUINT_PTR=INT
PUINT32=INT
PUINT64=LONG
PULARGE_INTEGER=LONG
PULONG_PTR=ADDR
PULONG32=INT
PULONG64=LONG
*/
	
	var tbyval = string.list(byval)
	var tbyref = string.list(byref)
	
	c2a = function(str){ 
		str = string.replace(str,"(\w)\t+(\w)", "\1 \2") 
		str = string.replace(str,"(\W)unsigned\s+long\s+long(\W)", "\1UINT64\2") 
		str = string.replace(str,"(\W)long\s+long(\W)", "\1INT64\2") 
		str = string.replace(str,"(\W)INT(\W)", "\1int\2") 
		str = string.replace(str,"(\W)const\s+SIZE\s*\*", "\1struct ") 
		str = string.replace(str,"(\W)const\s+POINT\s*\*", "\1struct ") 
		str = string.replace(str,"(\W)const\s+RECT\s*\*", "\1struct ") 
		str = string.replace(str,"(\W)__in_opt\s+SIZE\s*\*", "\1struct ") 
		str = string.replace(str,"(\W)__in_opt\s+POINT\s*\*", "\1struct ") 
		str = string.replace(str,"(\W)__in_opt\s+RECT\s*\*", "\1struct ") 
		str = string.replace(str,"(\W)_In_opt_\s+SIZE\s*\*", "\1struct ") 
		str = string.replace(str,"(\W)_In_opt_\s+POINT\s*\*", "\1struct ") 
		str = string.replace(str,"(\W)_In_opt_\s+RECT\s*\*", "\1struct ") 
		str = string.replace(str,"(\W)_In_\s+SIZE\s*\*", "\1struct ") 
		str = string.replace(str,"(\W)_In_\s+POINT\s*\*", "\1struct ") 
		str = string.replace(str,"(\W)_In_\s+RECT\s*\*", "\1struct ") 
		str = string.replace(str,"(\W)__out_opt\s+SIZE\s*\*", "\1struct &") 
		str = string.replace(str,"(\W)__out_opt\s+POINT\s*\*", "\1struct &") 
		str = string.replace(str,"(\W)__out_opt\s+RECT\s*\*", "\1struct &") 
		str = string.replace(str,"(\W)_Out_opt_\s+SIZE\s*\*", "\1struct &") 
		str = string.replace(str,"(\W)_Out_opt_\s+POINT\s*\*", "\1struct &") 
		str = string.replace(str,"(\W)_Out_opt_\s+RECT\s*\*", "\1struct &") 
		str = string.replace(str,"(\W)__out\s+SIZE\s*\*", "\1struct &") 
		str = string.replace(str,"(\W)__out\s+POINT\s*\*", "\1struct &") 
		str = string.replace(str,"(\W)__out\s+RECT\s*\*", "\1struct &") 
		str = string.replace(str,"(\W)_Out_\s+SIZE\s*\*", "\1struct &") 
		str = string.replace(str,"(\W)_Out_\s+POINT\s*\*", "\1struct &") 
		str = string.replace(str,"(\W)_Out_\s+RECT\s*\*", "\1struct &") 
		str = string.replace(str,"(\W)__inout\s+", "\1")  
		str = string.replace(str,"(\W)__out_opt\s+", "\1") 
		str = string.replace(str,"(\W)__out\s+", "\1")  
		str = string.replace(str,"(\W)_Out_opt_\s+", "\1") 
		str = string.replace(str,"(\W)_Out_\s+", "\1")  
		str = string.replace(str,"(\W)__in_opt\s+", "\1") 
		str = string.replace(str,"(\W)__in\s+", "\1")  
		str = string.replace(str,"(\W)_In_opt_\s+", "\1") 
		str = string.replace(str,"(\W)_In_\s+", "\1")  
		str = string.replace(str,".+?(%\{\})\s*([\w_]+).+", "class \2 \1") 
		str = string.replace(str,"(\W)SIZE\s*\*", "\1struct &") 
		str = string.replace(str,"(\W)POINT\s*\*", "\1struct &") 
		str = string.replace(str,"(\W)RECT\s*\*", "\1struct &") 
		str = string.replace(str,"(\W)const\s+[A-Z_]{7,}\s*\*", "\1struct ") 
		str = string.replace(str,"(\W)[A-Z_]{7,}\s*\*", "\1struct&") 
		str = string.replace(str,"(\W)unsigned\s*__int64(\W)", "\1UNIT64\2")
		str = string.replace(str,"(\W)__int64(\W)", "\1long\2")
 		str = string.replace(str,"(\W)HDC(\W)", "\1pointer\2") 
 		str = string.replace(str,"(\W)POINT(\W)", "\1struct\2") 
 		str = string.replace(str,"(\W)SIZE(\W)", "\1struct\2") 
 		str = string.replace(str,"(\W)HDC(\W)", "\1pointer\2") 
 		str = string.replace(str,"(\W)HDC(\W)", "\1pointer\2") 
 		str = string.replace(str,"(\W)HDC(\W)", "\1pointer\2") 
 		str = string.replace(str,"(\W)HDC(\W)", "\1pointer\2") 
 		str = string.replace(str,"(\W)HMENU(\W)", "\1pointer\2") 
		str = string.replace(str,"(\W)INT(\W)", "\1int\2") 
		str = string.replace(str,"(\W)DWORD(\W)", "\1INT\2") 
		str = string.replace(str,"(\W)ULONG(\W)", "\1INT\2") 
		str = string.replace(str,"(\W)UINT(\W)", "\1INT\2") 
		str = string.replace(str,"(\W)unsigned\s*long(\W)", "\1INT\2")
		str = string.replace(str,"(\W)unsigned\s*int(\W)", "\1INT\2")
		str = string.replace(str,"(\W)FLOAT(\W)", "\1INT\2") 
		str = string.replace(str,"(\W)PVOID(\W)", "\1pointer\2") 
		str = string.replace(str,"(\W)LPVOID(\W)", "\1pointer\2") 
		str = string.replace(str,"(\W)LPCVOID(\W)", "\1pointer\2") 
		str = string.replace(str,"void\s*\*\s*", "pointer ") 
		str = string.replace(str,"(\W)BOOL(\W)", "\1int\2") 
		str = string.replace(str,"(\W)long(\W)", "\1int\2") 
		str = string.replace(str,"(\W)LRESULT(\W)", "\1addr\2") 
		str = string.replace(str,"(\W)LPARAM(\W)", "\1addr\2") 
		str = string.replace(str,"(\W)WPARAM(\W)", "\1ADDR\2") 
		str = string.replace(str,"(\W)HWND(\W)", "\1addr\2") 
		str = string.replace(str,"(\W)HINSTANCE(\W)", "\1pointer\2") 
		str = string.replace(str,"(\W)HKEY(\W)", "\1pointer\2") 
		str = string.replace(str,"(\W)HANDLE(\W)", "\1pointer\2") 
		str = string.replace(str,"\n\N*#\N+", "")  
		str = string.replace(str,"(\W)LPCSTR(\W)", "\1string\2")  
		str = string.replace(str,"(\W)LPCTSTR(\W)", "\1ustring\2")  
		str = string.replace(str,"(\W)LPSTR(\W)", "\1string\2") 
		str = string.replace(str,"(\W)LPTSTR(\W)", "\1ustring\2") 
		str = string.replace(str,"(\W)const\s+RECT\s*\*", "\1struct ") 
		str = string.replace(str,"(\W)const\s+char\s*\*", "\1string ")  
		str = string.replace(str,"(\W)const\s+unsigned\s*\char\s*\*(\W)", "\1string\2") 
		str = string.replace(str,"(\W)char\s*\*(\W)", "\1string\2")  
		str = string.replace(str,"(\W)unsigned\s*\char\s*\*(\W)", "\1string\2")  
		str = string.replace(str,"(\W)BYTE\s*\*(\W)", "\1string\2") 
		str = string.replace(str,"(\W)unsigned short(\W)", "\1WORD\2") 
		str = string.replace(str,"(\W)USHORT(\W)", "\1WORD\2")
		str = string.replace(str,"(\W)SHORT(\W)", "\1WORD\2") 
		str = string.replace(str,"(\W)short(\W)", "\1word\2")  
		str = string.replace(str,"(\W)char(\W)", "\1byte\2") 
		str = string.replace(str,"union[^\w_]+(%{}?)\s*([\w_]+)", "union \2=\1")  
		str = string.replace(str," +", " ")
		str = string.replace(str,"(\W)LPCSTR(\W)", "\1string\2")   
    	//下面这句一定要放在最后
    	str = string.replace(str,"(\W)unsigned(\W)", "\1INT\2")
    	return str;
	}
	
	var dll = "dll"
	api2aardio = function(code){
		var converApi = function(str){
			for(k,v in tbyval){
   				if(! tonumber(k) ){
   					str = ..string.replace(str,"(\W)"+k+"(\W)", "\1"+v+"\2")  
   				}
			}
			for(k,v in tbyref){
   				if(! tonumber(k) ){
   					str = ..string.replace(str,"(\W)"+k+"(\W)", "\1"+v+"&\2") 
   				}
			}
			str = ..string.replace(str,"\*","&")
			return str;
		}
		
		code = string.replace(code,"@__declspec(dllimport)","");
		code = string.replace(code,"@__declspec(dllexport)","");
		code = string.replace(code,`extern\s*"C"\s* `,"");
		code = string.replace(code,"(\W)WINAPI(\W)", "\1\2") 
		code = string.replace(code,"(\W)__in(\W)", "\1\2") 
		code = ..string.replace(code,"([\w_]+)\s+([\w_]+)\s*(%())",function(c,c2,c3){
			if(::User32[c2]) dll = "::User32"
			if(::Kernel32[c2]) dll = "::Kernel32"
			return ..string.format('%s = %s.api("%s","%s")',  c2, dll, c2, converApi(c+c3) );
		} )
		return code;
	}
	
	struct2aardio = function(str){
		str =" " + str + " "; //简化(\W)\w+(\W)
		
		str = c2a(str);
		str = api2aardio(str);
		str = string.replace(str,"(\W)\w+\s*\*", "\1pointer ") 
		
		for(k,v in tbyval){
   			if(! tonumber(k) ){
   				str = ..string.replace(str,"(\W)"+k+"(\W)", "\1"+v+"\2") 
   			}
		}
		for(k,v in tbyref){
   			if(! tonumber(k) ){
   				str = ..string.replace(str,"(\W)"+k+"(\W)", "\1pointer\2") 
   			}
		}
		
		str = string.trimleft(str);//去掉函数在左侧补偿的空格 
		return str;
	} 
	
	var ccode = winform.txtCode.text;
	dll =  string.match( ccode,"(\w+).dll(\W)"); 
	dll ?= string.lower(dll) 
	select(dll) {
		case "kernel32"
		{
			dll="::Kernel32"
		}
		case "user32"
		{
			dll="::User32"
		} 
		case "shell32"
		{
			dll="::Shell32"
		} 
		else{
		    dll="dll"
		}
		
	}
	
	winform.txtCode.text = struct2aardio(winform.txtCode.text); 
} 
 
import win.guid;
winform.btnGuid2Aardio.oncommand = function(id,event){
	var code = winform.txtCode.text;
	code = string.replace(code
		,"\{\s*(0x\x+)\s*,\s*(0x\x+)\s*,\s*(0x\x+)\s*,\s*\{\s*0x(\x\x)\s*,\s*0x(\x\x)\s*,\s*0x(\x\x)\s*,\s*0x(\x\x)\s*,\s*0x(\x\x)\s*,\s*0x(\x\x)\s*,\s*0x(\x\x)\s*,\s*0x(\x\x)\s*\}\s*\}"
		,function(c1,c2,c3,c41,c42,c43,c44,c45,c46,c47,c48){
			var s = string.format("win.guid(%s,%s,%s,'\x%s\x%s\x%s\x%s\x%s\x%s\x%s\x%s')",c1,c2,c3,c41,c42,c43,c44,c45,c46,c47,c48 )
			var s2 = eval(s);
			return s + '\n\t//\'' + s2.hex() + "'";
		}
	);
	code = string.replace(code,"#define","//#define");
	winform.txtCode.text = code;
	
}

winform.enableDpiScaling();
winform.show(true) 
win.loopMessage( winform );
