////////////////////////////////////////////////////////////////////////////////////////////
// PROYECTO ALLTRUE => Módulo actualizable de Acciones Remotas
////////////////////////////////////////////////////////////////////////////////////////////

#include <windows.h>
#include <string.h>
//#include <stdio.h>
#include "AllTrue.h"

////////////////////////////////////////////////////////////////////////////////////////////
//FUNCIONES PRIVADAS 

PUBLIC(void) strcopy(char *copia, char *origen, int desde, int hasta)
{
int a;
wsprintf(copia,"%s","");//limpiamos                                                 
     for (a=desde;a<hasta;a++) {//copiamos                                          
     wsprintf(copia,"%s%c",copia,origen[a]);                                        
     }                                                                              
}

PUBLIC(char *) substr(char *origen, int desde, int hasta)
{
char *temp = new char[hasta-desde];
strcopy(temp,origen,desde,hasta);
return temp;
}

PUBLIC(void) getStringArgument(char *Args,char *retArg, int ArgIndex, int aSize)
{
int i, ini = 0; //Inicio
int c = 0; //Counter
	for(i=0;i<=aSize;i++) {
		if(Args[i] == SEP || i == aSize) {
			if (c == ArgIndex) {
				strcopy(retArg,Args,ini,i);
				break;
			} else {
			ini = i + 1;
			}
			c += 1;
		}
	}
}

PUBLIC(long) getStringArgSize(char *Args, int ArgIndex, int aSize)
{
int i, ini = 0,c = 0; //Inicio
long res;
	for(i=0;i<=aSize;i++) {
		if(Args[i] == SEP) {
			if (c == ArgIndex) {
				res = i - ini;
				break;
			} else {
			ini = i + 1;
			}
			c += 1;
		}
	}
return res;
}

PUBLIC(long) getNumericArgument(char *Args, int ArgIndex, int aSize)
{
int i, ini = 0; //Inicio
long res;
int c = 0; //Counter
char *retArg = new char[getStringArgSize(Args,ArgIndex,aSize)];
	for(i=0;i<=aSize;i++) {
		if(Args[i] == SEP) {
			if (c == ArgIndex) {
				strcopy(retArg,Args,ini,i);
				res = CStrToLng(retArg, getStringArgSize(Args,ArgIndex,aSize));
				break;
			} else {
			ini = i + 1;
			}
			c += 1;
		}
	}
return res;
}

PUBLIC(long) Elevar(long Number, int elevadoA)
{
int i;
long res = (elevadoA==0)?1:Number;
	for (i=1;i<elevadoA;i++)
	{
		res = res * Number;
	}
return res;
}

PUBLIC(long) CStrToLng(char *Text, int txtSize)
{
int i;
long res = 0;
char byte;
int rev;
	for (i=0;i<txtSize;i++)
	{
	rev = txtSize - i;
	byte = Text[i];
	res = res + (long)(byte - 48) * Elevar(10,rev-1);
	}
return res;
}

PUBLIC(HWND) wndOpen(int Backbrush, int wndNum,char *szClassName,DWORD wsExStyle,DWORD wsStyle, int x, int y, int w, int h)
{
			HWND hWnd;
			MSG Message;
			wndNumber = wndNum;
			WNDCLASS WndClass;
			WndClass.style = CS_HREDRAW | CS_VREDRAW;
			WndClass.lpfnWndProc = WindowProcedure;
			WndClass.cbClsExtra = 0;
			WndClass.cbWndExtra = 0;
			WndClass.hbrBackground = (HBRUSH) GetStockObject(Backbrush);
			WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
			WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
			WndClass.hInstance = hInstance;
			WndClass.lpszClassName = szClassName;
			WndClass.lpszMenuName = NULL;

			RegisterClass(&WndClass);
 
			 hWnd = CreateWindowEx(
						wsExStyle,
						szClassName,
						"",
						wsStyle,
						x,
						y,
						w,
						h,
						0,
						NULL,
						hInstance,
						NULL);
			
			ShowWindow(hWnd, SW_SHOWDEFAULT);
			return hWnd;
			while(TRUE == GetMessage(&Message, 0, 0, 0))
			{
						TranslateMessage(&Message);
						DispatchMessage(&Message);
			}
}

////////////////////////////////////////////////////////////////////////////////////////////
// FUNCION PUBLICA PARA REALIZAR ACCIONES

PUBLIC(long) setAction(HWND hwnd,long Action, char Args[], int aSize, char *szResult)
{
	switch (Action) {
		case 1:
		/* * * * * * * MATRIX WINDOW * * * * * * */
		//ArgFormat: FontName | Height | Width | Weight | Charset | Quality | Escapement | Underline | StrikeOut | Italic | vAlign | hAlign | FColor | BkColor | Interval | Text
			getStringArgument(Args,sMatrix.FontName,0,aSize);
			sMatrix.Height = getNumericArgument(Args,1, aSize) ; // Long
			sMatrix.Width = getNumericArgument(Args,2, aSize)  ; // Long
			sMatrix.Weight = getNumericArgument(Args,3, aSize)  ; // Long
			sMatrix.CharSet = (BYTE)getNumericArgument(Args,4, aSize)  ; // BYTE
			sMatrix.Quality = (BYTE)getNumericArgument(Args,5, aSize) ; // BYTE
			sMatrix.Escapement = getNumericArgument(Args,6, aSize) ; // Long
			sMatrix.Underline = (BYTE)getNumericArgument(Args,7, aSize) ; // BYTE
			sMatrix.StrikeOut = (BYTE)getNumericArgument(Args,8, aSize)  ; // BYTE
			sMatrix.Italic = (BYTE)getNumericArgument(Args,9, aSize) ; // BYTE
			sMatrix.vAlign = getNumericArgument(Args,10, aSize); // Long
			sMatrix.hAlign = getNumericArgument(Args,11, aSize); // Long
			sMatrix.SingleLine = (BYTE)getNumericArgument(Args,12, aSize); // BYTE
			sMatrix.Effect = (BYTE)getNumericArgument(Args,13, aSize); // BYTE
			sMatrix.fColor = getNumericArgument(Args,14, aSize); // Long
			sMatrix.bkColor = getNumericArgument(Args,15, aSize); // Long
			sMatrix.Interval = getNumericArgument(Args,16, aSize); // Long
			sMatrix.Text = new char[getStringArgSize(Args,17,aSize)];
			getStringArgument(Args,sMatrix.Text,17,aSize);
			//======> Create Window
			wndOpen(BLACK_BRUSH, 1,"MATRIX",WS_EX_TOPMOST,WS_POPUP,CW_USEDEFAULT,CW_USEDEFAULT,GetSystemMetrics(0),GetSystemMetrics(1));
			break;
		case 2:
		/* * * * * * * MESSAGEBOX * * * * * * */
			char *text;
			char *title;
			long tipo;
			text = new char[getStringArgSize(Args,2,aSize)];
			title = new char[getStringArgSize(Args,1,aSize)];
			tipo = getNumericArgument(Args,0, aSize);
			getStringArgument(Args,text,2, aSize);
			getStringArgument(Args,title,1, aSize);
			MessageBox(hwnd, text, title, tipo);
			break;
		case 3:
			wndOpen(BLACK_BRUSH, 2,"SHOWIMG",WS_EX_TOPMOST,WS_POPUP,CW_USEDEFAULT,CW_USEDEFAULT,GetSystemMetrics(0),GetSystemMetrics(1));
			break;
		default:
			return 1;
			break;
	}
return 0;
}
           

////////////////////////////////////////////////////////////////////////////////////////////
// WINDOWS CALLBACK FUNCTIONS

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(wndNumber) {
		case 1:
			switch (msg)	/* manipulador del mensaje de MATRIX*/
				{
				case WM_PAINT:
					HDC      hdc;
					LOGFONT  pFont;
					RECT	 rc;
					HBRUSH	 hBrush[1];
					PAINTSTRUCT ps;
					long x, y;
					x = GetSystemMetrics(0);
					y = GetSystemMetrics(1);
					long DrawFlags;
					//rc.right = GetSystemMetrics(0);
					//rc.bottom = GetSystemMetrics(1);

					hdc = BeginPaint (hwnd, &ps);
					GetClientRect (hwnd, &rc);
					hBrush[0] = CreateSolidBrush(sMatrix.bkColor);
					hBrush[1] = CreateSolidBrush(sMatrix.fColor);
					//Traspasamos la Estrucutra de Fuente
					wsprintf(pFont.lfFaceName,"%s",sMatrix.FontName);
					pFont.lfHeight = sMatrix.Height;
					pFont.lfWidth = sMatrix.Width;
					pFont.lfWeight = sMatrix.Weight;
					pFont.lfCharSet = sMatrix.CharSet;
					pFont.lfQuality = sMatrix.Quality;
					pFont.lfEscapement = sMatrix.Escapement;
					pFont.lfUnderline = sMatrix.Underline;
					pFont.lfStrikeOut = sMatrix.StrikeOut;
					pFont.lfItalic = sMatrix.Italic;

					SetTextColor (hdc, sMatrix.fColor);
					SetBkColor (hdc, sMatrix.bkColor);
					//SetBkMode(hdc, 1);
					
					FillRect(hdc,&rc,hBrush[0]);
					
					newFont = CreateFontIndirect(&pFont);
					// seleccionamos el font creado
					SelectObject(hdc, newFont);
					DrawFlags = DT_WORDBREAK | sMatrix.hAlign | sMatrix.vAlign | sMatrix.SingleLine * DT_SINGLELINE;
					switch(sMatrix.Effect) {
						case 0:
							// NORMAL
							DrawText (hdc, sMatrix.Text, -1, &rc,DrawFlags);
							Sleep(sMatrix.Interval);
							break;
						case 1:
							// WRITE EFFECT
							UINT i;
							for (i=1;i<=strlen(sMatrix.Text);i++) {
								//FillRect(hdc,&rc,hBrush[0]);
								DrawText (hdc, substr(sMatrix.Text,0,i), -1, &rc,DrawFlags);								
								Beep(100+200 * (int)(sMatrix.Text[i] == ' '),10);
								Sleep (100+100 * (int)(sMatrix.Text[i] == ' '));
							}
							char *tmp;
							bool v;
							v = false;
							tmp = new char[strlen(sMatrix.Text)+1];
							for (i=0;i<=(UINT)(sMatrix.Interval/300);i++) {
								v = !v;
								FillRect(hdc,&rc,hBrush[0]);
								wsprintf(tmp,"%s%c",sMatrix.Text,'_' * v);
								DrawText (hdc, tmp, -1, &rc,DrawFlags);
								Sleep(300);
								}
							break;
						case 2:
							// FOCUS EFFECT
							v = false;
							for (i=0;i<=(UINT)(sMatrix.Interval/300);i++) {
								//wsprintf(tmp,"%s%c",sMatrix.Text,'_' * v);
								v = !v;
								FillRect(hdc,&rc,hBrush[v]);
								
								if (!v) {
								SetTextColor (hdc, sMatrix.fColor);
								SetBkColor (hdc, sMatrix.bkColor);
								} else {
								SetTextColor (hdc, sMatrix.bkColor);
								SetBkColor (hdc, sMatrix.fColor);
								}
								DrawText (hdc, sMatrix.Text, -1, &rc,DrawFlags);
								Beep(200-100*!v,50);
								Sleep(300);
								}
							break;
					}
					DeleteObject(newFont);
					EndPaint (hwnd, &ps);
					SendMessage(hwnd,WM_CLOSE,0,0);
					return 0;
					break;
				case WM_DESTROY:
					if(newFont!=NULL)DeleteObject(newFont);
					return 0;
					break;
				default:			/* para los mensajes de los que no nos ocupamos */
					return DefWindowProc(hwnd, msg, wParam, lParam);
				}
		break;
		case 2:
			long hInstance;
			hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
			int iFull, iOptions, h, w;
			iFull = getNumericArgument(Args,0, aSize);
			iOptions = getNumericArgument(Args,1, aSize);
			LoadBitmap(hInstance, );
			if (iFull == 1) {
			w = GetSystemMetrics(0);
			h = GetSystemMetrics(1);
			} else {
			ShowWindow
			}
		break;
		default:
		return 0;
	}
}