#include "H\General.H"
#include "H\Calc.H"

typedef struct DCalc {
	FormType 	   *f;
	UInt8          tpc;
	UInt16         x,y,w,h,w1,w2,w3,xp,yp,x1;
	UInt8		   cc[8][6];
	UInt8          cb[11];
	UInt16         tec;
	Boolean        hm;
	double         m,r,z,v;
	Char           pv,op;
	Boolean        pi,vr;
	RectangleType  rp,ra,rx;
	UInt16         py;
	Char           st[50];
	UInt8          ps;
	UInt8          vp, vc;
	Boolean        red;
	Boolean        pd;
	// Para menejo de etiquetas de controles internos
	Char           s1[60],s2[60],s3[25],s4[60];
	// Para regreso de info
	FormType       *fr;
	double         *re;
} Calc;
Calc  		*xcal;
MemHandle 	mcal;


#define IVA  15
#define VTOP 8
typedef struct DPsBC  { UInt16 x,y,w,h; } PsBC;

#define CalcCancela								  1000
#define CalcAcepta								  1001
#define CalcAyuda								  1002
#define CalcOper								  1003



Char 	ValC		  (UInt16) 										 	ES1;
UInt8 	Cint		  (Char) 										 	ES1;
Char 	Cstr		  (UInt8) 										 	ES1;
double 	AjusteC		  (void)     								 	 	ES1;
void    LetrasTeclaC  (Char*,UInt16,UInt8*)	     						ES1;
void 	PosDimBTC	  (UInt16,PsBC*,UInt16*)      					 	ES1;
void 	PonLetraC	  (Char*,UInt16,UInt16,UInt16,UInt16,UInt8) 	 	ES1;
void 	PintaTecC	  (UInt16,UInt16,UInt16,UInt16,UInt16)	    	 	ES1;
void 	PintaBotonC	  (UInt16,Boolean,Boolean) 	 					 	ES1;
void 	PintaMem	  (void) 										 	ES1;
void 	PintaSig	  (void) 										 	ES1;
void 	PintaCalc	  (UInt16,Boolean,Boolean)						 	ES1;
void 	PonValor	  (void) 										 	ES1;
void 	PonDatos	  (void) 										 	ES1;
Char 	PDec		  (void) 										 	ES1;
void 	AgregaC		  (UInt16) 										 	ES1;
void 	OpeV		  (Char) 										 	ES1;
void 	OpeM		  (Char) 										 	ES1;
void 	OpeR		  (Char) 										 	ES1;
void 	OpeI		  (void) 										 	ES1;
void 	OperaTecladoC (void) 										 	ES1;
Boolean EnPosC	      (UInt16,UInt16,UInt16) 						 	ES1;
UInt16 	EnTecladoC	  (UInt16,UInt16) 								 	ES1;
void 	CIma		  (Int16,Int16,Int16)							 	ES1;
void 	Fnd			  (Coord,Coord,UInt16)							 	ES1;
void 	DColor		  (UInt16,UInt8 *,UInt8 *,UInt8 *)				 	ES1;
void 	Intens		  (UInt8 *,UInt8 *,UInt8 *,UInt8)				 	ES1;
void 	IniciaColoresC(Boolean,RectangleType*,UInt8,double)	 			ES1;
void 	IniRedondeo   (Boolean)				    					 	ES1;
void 	PntMarco	  (UInt16,UInt16,UInt16,UInt16,UInt16,UInt16) 	 	ES1;
void 	PntInt		  (RectangleType*,UInt8,Char*,UInt8,UInt8,Boolean) 	ES1;
Boolean EnControlProp (UInt16,UInt16,UInt16)		 				   	ES1;

// Rutinas de conversión -----------------------------------------------
Char ValC(UInt16 t) {
	switch(t) {
		case 12: return('7');	case 13: return('8');	case 14: return('9');
		case 22: return('4');	case 23: return('5');	case 24: return('6');
		case 32: return('1');	case 33: return('2');	case 34: return('3');
		case 42: return('0');   case 43: return(PrefGen(5));
		default: return('0');
	}
}
double AjusteC(void) {
long   c,d,e,r,w;
double v;
	d=(long)((double)(xcal->v*(double)100)); e=d/100; r=d-(e*100);
	d=e/10; d=d*10; d=e-d;
	c=e/100; c*=100; c=(e-c)/10; v=e;
	switch(xcal->xp) {
		case 1: if (r!=0) v+=((xcal->yp==1)?1:-1); break;
		case 2: if ((d==5 || d==0) && r==0) break;
		        if (xcal->yp==1) if (d<5) v+=(5-d); else v+=(10-d);
		        else             if (d<5) v-=d;     else v-=(d-5); break;  
		case 3: if (d==0 && r==0) break;
		        if (xcal->yp==1) { if (d>0 || r>0) v+=(10-d); }
		        else v-=d; break;
		case 4: if ((c==5 || c==0) && r==0 && d==0) break;
		        w=(c*10)+d;
		        if (xcal->yp==1) if (c<5) v+=(50-w); else v+=(100-w);
		        else             if (c<5) v-=w;      else v-=(w-50); break;
	}
	return v;
}
void LetrasTeclaC(Char *r, UInt16 tp, UInt8 *l) {
	StrCopy(r," ");
	switch(tp) {
	  case  1: if      (xcal->tpc==0) SacaTexto(r,5000,0,50);
	           else if (xcal->tpc==1 || xcal->tpc==2) StrCopy(r,"7");  break;
	  case  2: if      (xcal->tpc==0) SacaTexto(r,5000,1,50);
	           else if (xcal->tpc==1 || xcal->tpc==2) StrCopy(r,"8");  break;
	  case  3: if (xcal->tpc==1 || xcal->tpc==2) StrCopy(r,"9");       break; 
	  case  4: StrCopy(r,"Ce"); break;
	  case  5: StrCopy(r,"C"); break;
	  case 11: if      (xcal->tpc==0) StrCopy(r,"Mc");
	           else if (xcal->tpc==1 || xcal->tpc==2) StrCopy(r,"4"); break;
   	  case 12: if      (xcal->tpc==0) StrCopy(r,"7");
	           else if (xcal->tpc==1 || xcal->tpc==2) StrCopy(r,"5");  break;
   	  case 13: if      (xcal->tpc==0) StrCopy(r,"8");
	           else if (xcal->tpc==1 || xcal->tpc==2) StrCopy(r,"6"); break;
   	  case 14: StrCopy(r,"9"); break;
   	  case 15: StrCopy(r,"/"); break;
	  case 21: if      (xcal->tpc==0) StrCopy(r,"Mr");
	           else if (xcal->tpc==1 || xcal->tpc==2) StrCopy(r,"1"); break;
   	  case 22: if      (xcal->tpc==0) StrCopy(r,"4");
	           else if (xcal->tpc==1 || xcal->tpc==2) StrCopy(r,"2"); break;
   	  case 23: if      (xcal->tpc==0) StrCopy(r,"5");
	           else if (xcal->tpc==1 || xcal->tpc==2) StrCopy(r,"3"); break;
   	  case 24: StrCopy(r,"6"); break;
   	  case 25: StrCopy(r,"*"); break;
   	  case 26: StrCopy(r,"%"); break;
	  case 31: if      (xcal->tpc==0) StrCopy(r,"Ms");
	           else if (xcal->tpc==1 || xcal->tpc==2) StrCopy(r,"0"); break;
   	  case 32: if      (xcal->tpc==0) StrCopy(r,"1");
	           else if (xcal->tpc==1 || xcal->tpc==2) StrCopy(r,(PrefGen(5)=='.')?".":",");  break;
   	  case 33: StrCopy(r,"2"); break;
   	  case 34: StrCopy(r,"3"); break;
   	  case 35: StrCopy(r,"-"); break; 
   	  case 36: StrCopy(r,"="); break;
   	  case 40: SacaTexto(r,5000,2,50); break;
	  case 41: StrCopy(r,"M+"); break;
   	  case 42: StrCopy(r,"0"); break;
   	  case 43: StrCopy(r,(PrefGen(5)=='.')?".":","); break;
   	  case 45: StrCopy(r,"+"); break;
	}
	*l=StrLen(r);
}
// Rutinas de pintar ----------------------------------------------------
void PntMarco(UInt16 x, UInt16 y, UInt16 w, UInt16 h, UInt16 c1, UInt16 c2) {
	WinSetForeColor(xcal->cb[c1]); 
           WinDrawLine(x,   y,   x+w, y); 
           WinDrawLine(x,   y,   x,   y+h-1); 
	WinSetForeColor(xcal->cb[c2]); 
           WinDrawLine(x,   y+h, x+w, y+h); 
           WinDrawLine(x+w, y+h, x+w, y+1);
}
void PntInt(RectangleType *rc, UInt8 c1, Char *st, 
            UInt8 c2, UInt8 c3, Boolean sel) {
UInt16 x,y;
	WinSetBackColor(xcal->cb[c1]); WinEraseRectangle(rc,0);
	if (st!=NULL) {
    	WinSetBackColor(xcal->cb[c2]); WinSetTextColor(xcal->cb[c3]); 
    	WinDrawChars(st,StrLen(st),rc->topLeft.x+16,rc->topLeft.y+2);
	}
	if (sel) {
		WinSetForeColor(xcal->cb[c3]); 
		x=rc->topLeft.x+2; y=rc->topLeft.y+2;
		WinDrawLine(x,y,x+4,y+4); WinDrawLine(x+4,y,x,y+4);
	}
}
void PintaRed(int op) {
RectangleType  rc;
double         v;
Char           t[150];
	rc.extent.x=rc.extent.y=9;
	if (op==0) {
		rc.topLeft.x=xcal->w1; rc.topLeft.y=xcal->w2; 
		PntInt(&rc,0,NULL,0,((xcal->w3==1)?1:8),(xcal->w3==1));
	}
	if (op==0 || op==1) {
		rc.topLeft.x=xcal->w1-2; rc.topLeft.y=xcal->w2+25; 
	    PntInt(&rc,((xcal->w3==1)?9:6),"1",6,((xcal->w3==1)?1:8),(xcal->xp==1));
	    rc.topLeft.x+=35; 
	    PntInt(&rc,((xcal->w3==1)?9:6),"5",6,((xcal->w3==1)?1:8),(xcal->xp==2));
		rc.topLeft.x=xcal->w1-2;  rc.topLeft.y+=14; 
	    PntInt(&rc,((xcal->w3==1)?9:6),"10",6,((xcal->w3==1)?1:8),(xcal->xp==3));
	    rc.topLeft.x+=35; 
	    PntInt(&rc,((xcal->w3==1)?9:6),"50",6,((xcal->w3==1)?1:8),(xcal->xp==4));
	}
    if (op==0 || op==2) {
		rc.topLeft.x=xcal->w1; rc.topLeft.y=xcal->w2+61;
		SacaTexto(t,5000,3,50);
	    PntInt(&rc,((xcal->w3==1)?9:6),t,6,((xcal->w3==1)?1:8),(xcal->yp==1));
	    rc.topLeft.y+=14;
		SacaTexto(t,5000,4,50);
	    PntInt(&rc,((xcal->w3==1)?9:6),t,6,((xcal->w3==1)?1:8),(xcal->yp==2));
    }
	if (op==0) {
		rc.topLeft.x=xcal->x1; rc.topLeft.y=xcal->w2;
		PntInt(&rc,0,NULL,0,((xcal->w3==2)?1:8),(xcal->w3==2));
	}
	if (op==0) PintaCalc(0,false,false);
	switch(xcal->w3) {
		case 2:
		case 0: Astr((double)xcal->v,xcal->st,&xcal->ps);
				PonValor();
				break;
		case 1: v=AjusteC();
				Astr((double)v,xcal->st,&xcal->ps);
				PonValor();
				break;
	}
}
void PosDimBTC(UInt16 tp, PsBC *p, UInt16 *c) {
UInt16  x,y,w,h,w1,w2,w3;
    w=xcal->w+2; h=xcal->h+1;
    if (xcal->tpc==0) { 
	    w1=xcal->w1+2; 
	    w2=xcal->w2+2; 
	    w3=xcal->w3+2;
	    switch(tp) {
	     case  1: x=0;       		  y=0; w=w3;   		*c=5; break;
	     case  2: x=w3;   		      y=0; w=w3;   		*c=5; break;
	     case  3: x=(2*w3)+1; 		  y=0; w=w2;   		*c=7; break;
	     case  4: x=(2*w3)+1+w2;      y=0; w=w2;   		*c=4; break;
	     case  5: x=(2*w3)+1+(2*w2);  y=0; w=w3;   		*c=4; break;
	     case 11: x= 0;               y=3+h; w=w1; 		*c=3; break;	
	     case 12: x= 5+w1;            y=3+h;       		*c=0; break;	
	     case 13: x= 5+w1+w;          y=3+h;       		*c=0; break;	
	     case 14: x= 5+w1+(w*2);      y=3+h;       		*c=0; break;	
	     case 15: x=10+w1+(w*3)-1;    y=3+h;       		*c=2; break;	
	     case 16: x=10+w1+(w*4);      y=3+h;       		*c=1; break;	
	     case 21: x= 0;               y=3+(2*h); w=w1;  *c=3; break;	
	     case 22: x= 5+w1;            y=3+(2*h);   		*c=0; break;	
	     case 23: x= 5+w1+w;          y=3+(2*h);   		*c=0; break;	
	     case 24: x= 5+w1+(w*2);      y=3+(2*h);   		*c=0; break;	
	     case 25: x=10+w1+(w*3)-1;    y=3+(2*h);   		*c=2; break;	
	     case 26: x=10+w1+(w*4);      y=3+(2*h);   		*c=1; break;	
	     case 31: x= 0;               y=3+(3*h); w=w1;  *c=3; break;	
	     case 32: x= 5+w1;            y=3+(3*h);   		*c=0; break;	
	     case 33: x= 5+w1+w;          y=3+(3*h);   		*c=0; break;	
	     case 34: x= 5+w1+(w*2);      y=3+(3*h);   		*c=0; break;	
	     case 35: x=10+w1+(w*3)-1;    y=3+(3*h);   		*c=2; break;	
	     case 36: x=10+w1+(w*4);      y=3+(3*h); h*=2;	*c=6; break;	
	     case 41: x= 0;               y=3+(4*h); w=w1;  *c=3; break;	
	     case 42: x= 5+w1;            y=3+(4*h);   		*c=0; break;	
	     case 43: x= 5+w1+w;          y=3+(4*h);   		*c=0; break;	
	     case 44: x= 5+w1+(w*2);      y=3+(4*h);   		*c=0; break;	
	     case 45: x=10+w1+(w*3)-1;    y=3+(4*h);   		*c=2; break;	
	    }
    }
    else if (xcal->tpc==1 || xcal->tpc==2) {
	    switch(tp) {
	     case  1: x=0;               	  y=0;      		*c=0; break;	
	     case  2: x=w;               	  y=0;       		*c=0; break;	
	     case  3: x=w*2;             	  y=0;       		*c=0; break;	
	     case 11: x=0;               	  y=h;       		*c=0; break;	
	     case 12: x=w;               	  y=h;       		*c=0; break;	
	     case 13: x=w*2;             	  y=h;       		*c=0; break;	
	     case 21: x=0;               	  y=(h*2);     		*c=0; break;	
	     case 22: x=w;               	  y=(h*2);     		*c=0; break;	
	     case 23: x=w*2;             	  y=(h*2);     		*c=0; break;	
	     case 31: x=0;               	  y=(h*3);     		*c=0; break;	
	     case 32: x=w;               	  y=(h*3);     		*c=0; break;	
	     case 33: x=w*2;                  y=(h*3);     		*c=0; break;	
	     case 40: p->x=xcal->xp+3; 
	              p->y=xcal->yp+5+(2*FntCharHeight());
	              p->w=70; p->h=h-1; *c=8; return;
	    }
	    y+=2;
    }
    p->x=x+xcal->x+1; p->y=y+xcal->y+3; p->w=w-2; p->h=h-1;
}
void PonLetraC(Char *l, UInt16 x, UInt16 y, UInt16 W, UInt16 H, UInt8 ll) {
UInt16 		  i,w=0,h;
    h=(UInt16)FntCharHeight()-2; 
    for (i=0;i<ll;i++) w+=(UInt16)FntCharWidth(l[i]);
   	x+=((1+W-w)/2); y+=((1+H-h)/2);
   	if (PrefGen(1)!=1) y--;
   	if (xcal->tpc==2 && xcal->w3!=2) WinSetTextColor(xcal->cb[8]);
    else WinSetTextColor(xcal->cb[2]);
    WinPaintChars(l,ll,x,y);
}
void PintaTecC(UInt16 tp, UInt16 x, UInt16 y, UInt16 W, UInt16 H) {
	if (PrefGen(1)==8) x--;
   	if (xcal->tpc==2 && xcal->w3!=2) WinSetForeColor(xcal->cb[8]);
    else WinSetForeColor(xcal->cb[2]);
    switch(tp) {
    	case  3: x+=6; y+=((H+1)/2);
    	         WinDrawLine(x,y,x+9,y); WinDrawLine(x,y+1,x+9,y+1);
    	         x++; y--; WinDrawLine(x,y,x,y+3);
    	         x++; y--; WinDrawLine(x,y,x,y+5);
                 break;    	        
        case 16: WinDrawLine(x+5,y+5,x+6,y+4); 
    	         WinDrawLine(x+6,y+4,x+6,y+8); 
    	         WinDrawLine(x+7,y+11,x+12,y+6); 
    	         WinDrawLine(x+12,y+9,x+15,y+12); 
    	         WinDrawLine(x+12,y+12,x+15,y+9); 
    	         break;
        case 44: WinDrawLine(x+4,y+6,x+8,y+6); 
    	         WinDrawLine(x+6,y+4,x+6,y+8); 
    	         WinDrawLine(x+8,y+11,x+14,y+5); 
    	         WinDrawLine(x+13,y+10,x+16,y+10); 
    	         break;
    	case 33: x+=6; y+=((H+1)/2);
    	         WinDrawLine(x,y,x+9,y); WinDrawLine(x,y+1,x+9,y+1);
    	         x++; y--; WinDrawLine(x,y,x,y+3);
    	         x++; y--; WinDrawLine(x,y,x,y+5);
                 break;
    }
}

void CIma(Int16 resID, Int16 x, Int16 y) {
MemHandle	resH;
BitmapPtr	resP;
	resH = DmGetResource(bitmapRsc, resID);
	resP = MemHandleLock(resH);
	WinDrawBitmap (resP, x, y);
	MemPtrUnlock(resP);
	DmReleaseResource(resH);
}

void Fnd(Coord cx, Coord cy, UInt16 yi) {
MemHandle	resH;
BitmapPtr	resP;
UInt16      x,y;
	resH = DmGetResource(bitmapRsc, 5000);
	resP = MemHandleLock(resH);
	y=yi; do { 
		x=0; do { WinDrawBitmap(resP,x,y); x+=80; } while (x<cx); y+=80;
	} while (y<cy);
	MemPtrUnlock(resP);
	DmReleaseResource(resH);
}

void PintaBotonC(UInt16 tp, Boolean ap, Boolean pb) {
RectangleType   r;
PsBC            p;
UInt16          x,y,c;
UInt8           l;
Char            lt[120];
Boolean         p_int;
	PosDimBTC(tp,&p,&c); x=p.x; y=p.y; p.h--;
    r.topLeft.x=x; r.topLeft.y=y; r.extent.x=p.w; r.extent.y=p.h;
	p_int=false;
	if      (xcal->tpc==0) p_int=(tp==3 || tp==16 || tp==44);
	else if (xcal->tpc==1) p_int=(tp==33);
	else if (xcal->tpc==2) p_int=(tp==33);
    if (PrefGen(1)<=VTOP) {
    	if (c==8 && xcal->tpc==1) c=1;
    	r.topLeft.x=x+1; r.topLeft.y=y+1; r.extent.x=p.w-1; r.extent.y=p.h-2;
    	WinSetBackColor(xcal->cc[c][4]); WinEraseRectangle(&r,0);
    	r.topLeft.x=x; r.topLeft.y=y; r.extent.x=p.w; r.extent.y=p.h;
	    	WinSetForeColor(xcal->cc[c][0]);
	    		WinDrawLine(x+2,     y,       x+p.w-2,   y);
	    		WinDrawLine(x,       y+2,     x,         y+p.h-2);
	    		WinDrawLine(x+2,     y+p.h,   x+p.w-2,   y+p.h);
	    		WinDrawLine(x+p.w,   y+2,     x+p.w,     y+p.h-2);
	    		WinDrawLine(x+1,     y+1,     x+1,       y+1);
	    		WinDrawLine(x+p.w-1, y+1,     x+p.w-1,   y+1);
	    		WinDrawLine(x+1,     y+p.h-1, x+1,       y+p.h-1);
	    		WinDrawLine(x+p.w-1, y+p.h-1, x+p.w-1,   y+p.h-1);
	    	if (!ap) {	
		    	WinSetForeColor(xcal->cc[c][1]);
		    		WinDrawLine(x+1,     y+2,     x+1, 		 y+p.h-2);
		    		WinDrawLine(x+2,     y+1,     x+p.w-2, 	 y+1);
		    	WinSetForeColor(xcal->cc[c][2]);
		    		WinDrawLine(x+2,     y+3,     x+2, 	     y+p.h-1);
		    		WinDrawLine(x+3,     y+2,     x+p.w-1, 	 y+2);
		    	WinSetForeColor(xcal->cc[c][3]);
		    		WinDrawLine(x+3,     y+4,     x+3, 		 y+p.h-2);
		    		WinDrawLine(x+4,     y+3,     x+p.w-2, 	 y+3);
		    		WinDrawLine(x+3,     y+p.h-1, x+p.w-2, 	 y+p.h-1);
		    		WinDrawLine(x+p.w-1, y+p.h-2, x+p.w-1, 	 y+2);
		    	WinSetForeColor(xcal->cc[c][5]);
		    		WinDrawLine(x+3,     y+2,     x+3, 		 y+2);
		    		WinDrawLine(x+2,     y+3,     x+2, 		 y+3);
		    	if (PrefGen(1)<4) {
		    		WinDrawLine(x+3,     y+2,     x+4, 		 y+2);
		    		WinDrawLine(x+2,     y+3,     x+2, 		 y+4);
		    	}
    	}
    	if (p_int) PintaTecC(tp,x+((ap)?1:0),y+((ap)?1:0),p.w,p.h);
    	else {
	      if (PrefGen(1)<4) { x--; y--; }
	      LetrasTeclaC(lt,tp,&l);
	      PonLetraC(lt,x+((ap)?3:2),y+((ap)?2:1),p.w,p.h,l);
	      WinSetForeColor(xcal->cc[c][5]);
	      if (PrefGen(1)<4) { x++; y++; }
	    }
    	if (ap) {
	    	WinSetForeColor(xcal->cc[c][5]);
	    		WinDrawLine(x+3,     y+p.h-1, x+p.w-2, 	 y+p.h-1);
	    		WinDrawLine(x+p.w-1, y+p.h-2, x+p.w-1, 	 y+2);
    	}
    }
    else { if (c==7) c=4; if (c==8) c=7; 
    	   if (pb) CIma(5001+c+((ap)?10:0),x,y);
    	   if (c!=7) {
	    	   if (p_int) PintaTecC(tp,x+((ap)?1:0),y+((ap)?1:0),p.w,p.h);
	    	   else {
		      	WinPushDrawState(); WinSetDrawMode(winOverlay);
				LetrasTeclaC(lt,tp,&l);
		       	PonLetraC(lt,x+((ap)?1:0),y+((ap)?1:0),p.w,p.h,l);
		        WinPopDrawState();
		       }
    	   }
    }
}
void PintaMem() {
RectangleType   r;
UInt16          x,y;
    if (xcal->tpc==1) return;
    r.topLeft.x=xcal->rp.topLeft.x-8; 
    r.topLeft.y=xcal->rp.topLeft.y; 
    r.extent.x=8; r.extent.y=7;
    WinSetBackColor(xcal->cb[0]); WinEraseRectangle(&r,0);
    if (xcal->hm) {
    	x=r.topLeft.x+2; y=r.topLeft.y+2;
    	WinSetForeColor(xcal->cb[1]); 
        WinDrawLine(x,y,x,y+4);     
        WinDrawLine(x,y,x+2,y+2);     
        WinDrawLine(x+2,y+2,x+4,y);     
        WinDrawLine(x+4,y,x+4,y+4);     
    }
}
void PintaSig() {
RectangleType   r;
UInt16          x,y;
    r.topLeft.x=xcal->rp.topLeft.x-8; 
    r.topLeft.y=xcal->rp.topLeft.y+7; 
    r.extent.x=8; r.extent.y=7;
    WinSetBackColor(xcal->cb[0]); WinEraseRectangle(&r,0);
    if (xcal->op>0) {
    	WinSetForeColor(xcal->cb[1]); 
    	x=r.topLeft.x+2; y=r.topLeft.y+1;
    	switch(xcal->op) {
    		case 4: WinDrawLine(x,y+2,x+4,y+2);
    		        WinDrawLine(x+2,y,x+2,y+4);
    		        break;
    		case 3: WinDrawLine(x,y+2,x+4,y+2);
    		        break;
    		case 2: WinDrawLine(x,y,x+4,y+4);
    		        WinDrawLine(x+4,y,x,y+4);
    		        break; 
    		case 1: WinDrawLine(x+4,y,x,y+4);
    		        break;
    	}
    }
}
void PintaCalc(UInt16 tp, Boolean ap, Boolean pb) {
UInt16 i;
    if (xcal->tpc==0) {
	    if (tp==0) {
	    	PintaMem();
			for (i=1;i<6;i++) PintaBotonC(i,   false,pb);
			for (i=1;i<7;i++) PintaBotonC(i+10,false,pb);
			for (i=1;i<7;i++) PintaBotonC(i+20,false,pb);
			for (i=1;i<7;i++) PintaBotonC(i+30,false,pb);
			for (i=1;i<6;i++) PintaBotonC(i+40,false,pb);
	    }
	    else { PintaBotonC(tp,ap,pb); if (ap) xcal->tec=tp; else xcal->tec=0; }
    }
    else if (xcal->tpc==1 || xcal->tpc==2) {
	    if (tp==0) {
			for (i=1;i<4;i++) PintaBotonC(i,   false,pb);
			for (i=1;i<4;i++) PintaBotonC(i+10,false,pb);
			for (i=1;i<4;i++) PintaBotonC(i+20,false,pb);
			for (i=1;i<4;i++) PintaBotonC(i+30,false,pb);
			if (xcal->tpc==1) PintaBotonC(40,false,pb);
	    }
	    else { PintaBotonC(tp,ap,pb); if (ap) xcal->tec=tp; else xcal->tec=0; }
    }
    if (xcal->tpc==1) WinSetBackColor(xcal->cb[7]);
}
// Rutinas de calculadora -----------------------------------------------
void PonDatos() {
Int16 			i;	
double  		v,q;
RectangleType  	rc;
UInt8           ps;
Char    		st[150],ss[150];
UInt16  		x,y,w=0,h,wx;
	v=Adbl(xcal->st);  
	wx=45; h=FntCharHeight();
	rc.extent.x=wx; rc.extent.y=h;
	WinSetTextColor(xcal->cb[8]); WinSetBackColor(xcal->cb[0]);
	q=v*(double)xcal->vp/(double)100; Astr(q,st,&ps);
	for (i=0,w=0;i<StrLen(st);i++) w+=(UInt16)FntCharWidth(st[i]);
	rc.topLeft.x=x=xcal->xp+32; rc.topLeft.y=y=xcal->yp;
	WinEraseRectangle(&rc,0); 
	if (w>wx) { SacaTexto(st,5000,5,50); 
		        for (i=0,w=0;i<StrLen(st);i++) w+=(UInt16)FntCharWidth(st[i]); }
	x+=wx-w; WinDrawChars(st,StrLen(st),x,y);
	q=v*(double)((double)1+(double)((double)xcal->vp/(double)100)); 
	Astr(q,st,&ps);
	for (i=0,w=0;i<StrLen(st);i++) w+=(UInt16)FntCharWidth(st[i]);
	rc.topLeft.x=x=xcal->xp+32; y+=h; rc.topLeft.y=y;
	WinEraseRectangle(&rc,0); 
	if (w>wx) { SacaTexto(st,5000,5,50); 
		        for (i=0,w=0;i<StrLen(st);i++) w+=(UInt16)FntCharWidth(st[i]); }
	x+=wx-w; WinDrawChars(st,StrLen(st),x,y);
	WinSetBackColor(xcal->cb[9]); WinSetTextColor(xcal->cb[1]); 
	wx=xcal->rx.extent.x;
	q=v*(double)((double)1+(double)((double)xcal->vp/(double)100))/(double)xcal->vc; 
	Astr(q,ss,&ps); PonComas(ss,st);
	for (i=0,w=0;i<StrLen(st);i++) w+=(UInt16)FntCharWidth(st[i]);
	WinEraseRectangle(&xcal->rx,0); 
	if (w>wx) { SacaTexto(st,5000,5,50); 
		        for (i=0,w=0;i<StrLen(st);i++) w+=(UInt16)FntCharWidth(st[i]); }
	x=xcal->rx.topLeft.x+xcal->rx.extent.x-2-w; y=xcal->rx.topLeft.y+1;
	WinDrawChars(st,StrLen(st),x,y);
	WinSetBackColor(xcal->cb[7]);
}
void PonValor() {
Int16   		i;	
Char    		st[150];
UInt16  		x,w=0;
	PonComas(xcal->st,st); 
	WinSetBackColor(xcal->cb[((xcal->tpc==2)?9:0)]);
    for (i=0,w=0;i<StrLen(st);i++) w+=(UInt16)FntCharWidth(st[i]);
    if (w>xcal->rp.extent.x) {
	   	xcal->ra.topLeft.x=xcal->rp.topLeft.x; 
	   	xcal->ra.extent.x=xcal->rp.extent.x;
    	WinEraseRectangle(&xcal->ra,0); 
    	SacaTexto(st,5000,5,50); 
		w=0; for (i=0;i<StrLen(st);i++) w+=(UInt16)FntCharWidth(st[i]);
        x=xcal->rp.topLeft.x+xcal->rp.extent.x-w-2; 
    	WinSetTextColor(xcal->cb[1]); WinDrawChars(st,StrLen(st),x,xcal->py+1);
    }
    else {
	   	x=xcal->rp.topLeft.x+xcal->rp.extent.x-w-2; 
	    if (xcal->ra.topLeft.x!=-1) WinEraseRectangle(&xcal->ra,0); 
	   	WinSetTextColor(xcal->cb[1]); WinDrawChars(st,StrLen(st),x,xcal->py+1);
	   	xcal->ra.topLeft.x=x; xcal->ra.extent.x=w;
    }
    if (xcal->tpc==1) PonDatos();
}
Char PDec() {
UInt8 i;
Char  pt;
   pt=PrefGen(5);
   for (i=0;i<StrLen(xcal->st);i++) if (xcal->st[i]==pt) 
   	 return(StrLen(xcal->st)-i-1);
   return 3;
}
void AgregaC(UInt16 q) {	// Operación de desplegado
Char   r;
UInt16 t;
	if (xcal->pv) { xcal->st[0]=' '; xcal->st[1]=0; xcal->ps=1; xcal->pv=false; }
	if (xcal->tpc==0) t=q;
	else if (xcal->tpc==1 || xcal->tpc==2) 
		{ if (q==33) t=3; else t=q+11; }
	switch(t) {
	 case  3: if (xcal->ps>2) { xcal->ps--; xcal->st[xcal->ps]=0; }
	          else { Astr((double)0,xcal->st,&xcal->ps); xcal->pv=true; } break;
	 case  5: xcal->r=0; xcal->vr=false; xcal->op=0; PintaSig();
	 case  4: xcal->st[1]=0; xcal->ps=1; xcal->pv=true; Astr((double)0,xcal->st,&xcal->ps); break;
	 case 44: xcal->st[0]=((xcal->st[0]==' ')?'-':' '); break;
	 case 43: 
	 default: r=PDec(); 
  	          if (r!=3 && t==43) return;
  	          if (r==2) return;
	          if (xcal->ps==27) return;
	          if (t==43 && xcal->ps==1) xcal->st[xcal->ps++]='0';
	          else if (xcal->st[xcal->ps-1]=='0' && xcal->ps==2) xcal->ps--;
		      xcal->st[xcal->ps++]=ValC(t); xcal->st[xcal->ps]=0;
		      break;
	}
	PonValor();
}
void OpeV(Char op) { 		// Operaciones sobre valor
double v,iv;
    v=Adbl(xcal->st); iv=(double)IVA; 
    switch(op) {
    	case 1: v=(double)((v*1000)/(iv+100))/10; break;
    	case 2: v=(v*10)*(double)(1+(iv/100))/10; break;
    	case 3: if (v!=0) v=(double)((double)1/v); break;
    	case 4: if (!xcal->vr) return; v=xcal->r*v/100; break;
    }
	Astr(v,xcal->st,&xcal->ps); PonValor(); xcal->pi=true; xcal->z=v;
}
void OpeM(Char op) {		// Operaciones en memoria
double v;
    if (op==3 || op==4) v=Adbl(xcal->st);
    switch(op) {
		case 1: xcal->hm=false; xcal->m=0; PintaMem(); break;
		case 2: Astr(xcal->m,xcal->st,&xcal->ps); PonValor(); break;
		case 3: xcal->m=v; xcal->hm=true; PintaMem(); break; 
		case 4: xcal->m+=v; if (!xcal->hm) { xcal->hm=true; PintaMem(); } break;
    }
}
void OpeR(Char op) {		// Operaciones sobre registro
double v;
    v=Adbl(xcal->st); 
    if (xcal->vr) {
    	if (!xcal->pv) {
    		xcal->r*=(double)10; v*=(double)10;
	    	switch(xcal->op) {
		    	case 1: if (v!=0) xcal->r/=v; break;
		    	case 2: xcal->r*=v; break;
		    	case 3: xcal->r-=v; break;
		    	case 4: xcal->r+=v; break;
	    	}
	    	xcal->r/=(double)10; Astr(xcal->r,xcal->st,&xcal->ps); PonValor();
    	}
    } else { xcal->r=v; xcal->vr=true; }
    xcal->op=op; PintaSig(); xcal->pv=true; xcal->pi=true;
}
void OpeI() {				// Operacion Igual
	if (xcal->vr) {
		if (xcal->pi) { xcal->z=Adbl(xcal->st); xcal->pi=false; }
		switch(xcal->op) {
	    	case 1: if (xcal->z!=0) xcal->r=xcal->r/xcal->z; break;
	    	case 2: xcal->r=xcal->r*xcal->z; break;
	    	case 3: xcal->r=xcal->r-xcal->z; break;
	    	case 4: xcal->r=xcal->r+xcal->z; break;
		}
		Astr(xcal->r,xcal->st,&xcal->ps); PonValor();
	}
	xcal->pv=true;
}
void OperaTecladoC() {
	if (xcal->tpc==0) switch(xcal->tec) {
		  case  1: OpeV(1); break;
		  case  2: OpeV(2); break;
	 	  case 16: OpeV(3); break;
	 	  case 26: OpeV(4); break;
	 	  case 11: OpeM(1); break;
	 	  case 21: OpeM(2); break;
	 	  case 31: OpeM(3); break;
	 	  case 41: OpeM(4); break;
	 	  case 15: OpeR(1); break;
	 	  case 25: OpeR(2); break;
	 	  case 35: OpeR(3); break;
	 	  case 45: OpeR(4); break;
	 	  case 36: OpeI();  break;
		  default: AgregaC(xcal->tec); break;
	} else 
	if (xcal->tpc==1 || xcal->tpc==2) { 
		if (xcal->tec==40) { IniRedondeo(true); return; }
		AgregaC(xcal->tec);
	}
	PintaCalc(xcal->tec,false,true);
}
// Inicialización de colores y otros ------------------------------------
void DColor(UInt16 c, UInt8 *r, UInt8 *g, UInt8 *b) {
	switch(c) {
		case 0:	*r=170; *g=170; *b=170; break;
		case 1:	*r=117; *g=177; *b=227; break;
		case 2:	*r=254; *g=244; *b=177; break;
		case 3:	*r=0;   *g=206; *b=103; break;
		case 4:	*r=255; *g=80;  *b=80;  break;
		case 5:	*r=182; *g=140; *b=109; break;
		case 6:	*r=165; *g=211; *b=176; break;
		case 7: *r=255; *g=168; *b=125; break;
	}
}
void Intens(UInt8 *r, UInt8 *g, UInt8 *b, UInt8 tp) {
UInt8 v=25, w=60;
    if (tp>10) { 
		tp-=10;
		if (tp==7) tp=0;
		if (!(tp&0x04)) { if (*r+w<255) *r+=w; else *r=255; }
		if (!(tp&0x02)) { if (*g+w<255) *g+=w; else *g=255; }
		if (!(tp&0x01)) { if (*b+w<255) *b+=w; else *b=255; }
		return;
	}
    if (tp&0x04) { if (*r>v) *r-=v; else *r=0; }
    if (tp&0x02) { if (*g>v) *g-=v; else *g=0; }
    if (tp&0x01) { if (*b>v) *b-=v; else *b=0; }
}
void IniciaColoresC(Boolean ini, RectangleType *rc, UInt8 tpc, double v) {
RGBColorType   r;
UInt8          i,pp,pt,pq;
UInt16         x,y,w,h;
Coord          cx,cy;
	WinGetWindowExtent(&cx,&cy); xcal->tpc=tpc;
    if (ini) {
	    switch(PrefGen(1)) {
			case  1: r.r=r.g=r.b=255; pp=(UInt8)WinRGBToIndex(&r);
	    		     r.r=r.g=r.b=  0; pt=(UInt8)WinRGBToIndex(&r);
			         for (i=0;i<8;i++) {
			         	xcal->cc[i][5]=pp;	xcal->cc[i][4]=pt;
	    			    xcal->cc[i][0]=xcal->cc[i][1]=xcal->cc[i][2]=
	    			                   xcal->cc[i][3]=xcal->cc[i][4];
			         }
			         xcal->cb[2]=xcal->cb[0]=pp;
			         xcal->cb[1]=pt;
			         xcal->cb[3]=pt;
			         xcal->cb[4]=pp;
			         xcal->cb[5]=pp;
			         xcal->cb[6]=pp;
			         xcal->cb[7]=pp;
			         xcal->cb[8]=pt;
			         xcal->cb[9]=pp;
			         xcal->cb[10]=pp;
			         break;
			case  2: r.r=r.g=r.b=255; pp=(UInt8)WinRGBToIndex(&r);
	    		     r.r=r.g=r.b= 64; pt=(UInt8)WinRGBToIndex(&r);
	    		     r.r=r.g=r.b=  0; pq=(UInt8)WinRGBToIndex(&r);
			         for (i=0;i<8;i++) {
			         	xcal->cc[i][5]=pp;	xcal->cc[i][4]=pt;
	    			    xcal->cc[i][0]=pq;
	    			    xcal->cc[i][1]=xcal->cc[i][2]=
	    			                   xcal->cc[i][3]=xcal->cc[i][4];
			         }
			         xcal->cb[3]=pt;
	    		     r.r=r.g=r.b=0; pt=(UInt8)WinRGBToIndex(&r);
			         xcal->cb[0]=pp;
			         xcal->cb[1]=pt;
			         xcal->cb[2]=pp;
			         r.r=r.g=r.b=192; 
	    		     xcal->cb[4]=xcal->cb[5]=(UInt8)WinRGBToIndex(&r);
			         xcal->cb[6]=pp;
			         xcal->cb[7]=pp;
			         xcal->cb[8]=pt;
			         xcal->cb[9]=pp;
			         xcal->cb[9]=pp;
					 break;		
	    	default: for (i=0;i<8;i++) {
	    				DColor(i,&r.r,&r.g,&r.b);
	    				pp=0; if (r.r>0) pp+=4; if (r.g>0) pp+=2; if (r.b>0) pp+=1;
	    				Intens(&r.r,&r.g,&r.b,pp+10); 
	    				xcal->cc[i][5]=(UInt8)WinRGBToIndex(&r);
	    				DColor(i,&r.r,&r.g,&r.b);
	    			    xcal->cc[i][4]=WinRGBToIndex(&r); Intens(&r.r,&r.g,&r.b,pp);
	    				xcal->cc[i][3]=WinRGBToIndex(&r); Intens(&r.r,&r.g,&r.b,pp);
	    				xcal->cc[i][2]=WinRGBToIndex(&r); Intens(&r.r,&r.g,&r.b,pp);
	    				xcal->cc[i][1]=WinRGBToIndex(&r); Intens(&r.r,&r.g,&r.b,pp);
	    				xcal->cc[i][0]=WinRGBToIndex(&r);
	    	         }
	    	         r.r=r.g=r.b=200; xcal->cb[0]=WinRGBToIndex(&r);
	    		     r.r=r.g=r.b=  0; xcal->cb[1]=xcal->cb[2]=WinRGBToIndex(&r);
	    	         r.r=r.g=r.b=255; xcal->cb[3]=WinRGBToIndex(&r);
	    	         r.r=163; r.g=163; r.b=200; xcal->cb[4]=WinRGBToIndex(&r);
	    	         r.r=117; r.g=177; r.b=227; xcal->cb[5]=WinRGBToIndex(&r);
	    	         r.r=154; r.g=154; r.b=206; xcal->cb[6]=WinRGBToIndex(&r);
	    	         r.r=251; r.g=254; r.b=154; xcal->cb[7]=WinRGBToIndex(&r);
	    	         r.r=128; r.g=128; r.b=128; xcal->cb[8]=WinRGBToIndex(&r);
	    	         r.r=204; r.g=204; r.b=255; xcal->cb[9]=WinRGBToIndex(&r);
			         xcal->cb[10]=xcal->cb[1];
	    	         break;
	    }
    }
	w=156; h=126; x=0; y=0; //y=cy-h; 
	xcal->w=20; xcal->h=17;
	xcal->hm=false; xcal->m=xcal->r=0;  
	xcal->vr=false; xcal->pv=true; xcal->pi=true;
	xcal->ra.topLeft.x=-1;
	rc->topLeft.x=x; rc->topLeft.y=y; rc->extent.x=w; rc->extent.y=h;
	if (PrefGen(1)<=VTOP) {
		rc->extent.y=cy;
		WinSetBackColor(xcal->cb[4]); WinEraseRectangle(rc,0);
		if (PrefGen(1)>1) {
			WinSetForeColor(xcal->cb[5]); x=0; y=rc->topLeft.y;
			while (x<rc->extent.x)  { WinDrawLine(x,y,x,y+rc->extent.y); x+=4; }
			while (y<=cy) { WinDrawLine(0,y,rc->extent.x,y); y+=4; }
		}
		rc->extent.y=h;
	}
	else Fnd(cx,cy,rc->topLeft.y);
	Astr((double)v,xcal->st,&xcal->ps);	
}
// Rutinas de control e inicialización ** CALCULADORA ** -----------------------
Boolean EnPosC(UInt16 i, UInt16 x, UInt16 y) {
PsBC   p;
UInt16 c;
	PosDimBTC(i,&p,&c);
	return (x>=p.x && y>=p.y && x<=p.x+p.w && y<=p.y+p.h);
}
UInt16 EnTecladoC(UInt16 x, UInt16 y) {
UInt16 i;
    if (xcal->tpc==0) {
		for (i=1;i<6;i++) if (EnPosC(i,x,y))    return i;
		for (i=1;i<7;i++) if (EnPosC(i+10,x,y)) return i+10;
		for (i=1;i<7;i++) if (EnPosC(i+20,x,y)) return i+20;
		for (i=1;i<7;i++) if (EnPosC(i+30,x,y)) return i+30;
		for (i=1;i<6;i++) if (EnPosC(i+40,x,y)) return i+40;
    }
    else if (xcal->tpc==1 || xcal->tpc==2) {
		for (i=1;i<4;i++) if (EnPosC(i,x,y))    return i;
		for (i=1;i<4;i++) if (EnPosC(i+10,x,y)) return i+10;
		for (i=1;i<4;i++) if (EnPosC(i+20,x,y)) return i+20;
		for (i=1;i<4;i++) if (EnPosC(i+30,x,y)) return i+30;
		if (xcal->tpc==1) if (EnPosC(40,x,y)) return 40;
    }
	return 0;
}
Boolean EnControlProp(UInt16 t, UInt16 x, UInt16 y) {
UInt16 xi,yi;
	xi=xcal->w1; yi=xcal->w2;
	if (x>=xi && x<=xi+10 && y>=yi && y<=yi+10) 
		{ xcal->w3=((xcal->w3==1)?0:1); PintaRed(0); return true; }	
	xi-=2; yi+=25;	
	if (x>=xi && x<=xi+10 && y>=yi && y<=yi+10) if (xcal->xp!=1)
		{ xcal->xp=1; PintaRed(1); return true; }	
	xi+=35;	
	if (x>=xi && x<=xi+10 && y>=yi && y<=yi+10) if (xcal->xp!=2)
		{ xcal->xp=2; PintaRed(1); return true; }	
	xi-=35; yi+=14;	
	if (x>=xi && x<=xi+10 && y>=yi && y<=yi+10) if (xcal->xp!=3)
		{ xcal->xp=3; PintaRed(1); return true; }	
	xi+=35;	
	if (x>=xi && x<=xi+10 && y>=yi && y<=yi+10) if (xcal->xp!=4)
		{ xcal->xp=4; PintaRed(1); return true; }
	xi=xcal->w1; yi=xcal->w2+61;
	if (x>=xi && x<=xi+10 && y>=yi && y<=yi+10) if (xcal->yp!=1)
		{ xcal->yp=1; PintaRed(2); return true; }
	yi+=14;
	if (x>=xi && x<=xi+10 && y>=yi && y<=yi+10) if (xcal->yp!=2)
		{ xcal->yp=2; PintaRed(2); return true; }
    xi=xcal->x1; yi=xcal->w2;
	if (x>=xi && x<=xi+10 && y>=yi && y<=yi+10)
		{ xcal->w3=((xcal->w3==2)?0:2); PintaRed(0); return true; }	
	return false;
}
void IniRedondeo(Boolean ini) {
RectangleType  rc;
double         v;
UInt16         i,xi,yi,x,y,w,h;
Char           st[160];
	v=Adbl(xcal->st); 
    v=v*(double)((double)1+(double)((double)xcal->vp/(double)100))/(double)xcal->vc; 
    xcal->v=v;
	IniciaColoresC(false,&rc,2,v); xcal->tec=0;
	xcal->w3=0; xcal->xp=2; xcal->yp=1;
	if (ini) {
		CtlShowControl(FrmGetObjectPtr(xcal->f, FrmGetObjectIndex(xcal->f,CalcCancela)));
		CtlShowControl(FrmGetObjectPtr(xcal->f, FrmGetObjectIndex(xcal->f,CalcAcepta)));
		CtlShowControl(FrmGetObjectPtr(xcal->f, FrmGetObjectIndex(xcal->f,CalcAyuda)));
		CtlHideControl(FrmGetObjectPtr(xcal->f, FrmGetObjectIndex(xcal->f,CalcOper)));
	}
	rc.topLeft.x+=3; xi=rc.topLeft.x; rc.topLeft.y+=2; rc.extent.x-=6;
	xcal->rx.topLeft.x=rc.topLeft.x; 
	xcal->rx.topLeft.y=rc.topLeft.y; 
	xcal->rx.extent.x=rc.extent.x; rc.extent.y=xcal->rx.extent.y=18;
	WinSetBackColor(xcal->cb[9]); WinEraseRectangle(&xcal->rx,0);
	yi=rc.topLeft.y+rc.extent.y+4;
	x=xcal->rx.topLeft.x; y=xcal->rx.topLeft.y; 
	w=xcal->rx.extent.x; h=xcal->rx.extent.y;
	PntMarco(x,y,w,h,1,3);
    WinSetTextColor(xcal->cb[1]); 
    x+=3; y+=3; SacaTexto(st,5000,7,50);      
	WinSetTextColor(xcal->cb[1]); WinDrawChars(st,StrLen(st),x,y+1);
	xcal->rx.topLeft.x+=90; xcal->rx.topLeft.y+=2; 
	xcal->rx.extent.x-=92;  xcal->rx.extent.y=14;
	WinSetBackColor(xcal->cb[9]); WinEraseRectangle(&xcal->rx,0);
	x=xcal->rx.topLeft.x; y=xcal->rx.topLeft.y; 
	w=xcal->rx.extent.x;  h=xcal->rx.extent.y;
	PntMarco(x,y,w,h,8,3);
	xcal->rx.topLeft.x++; xcal->rx.topLeft.y++;
	xcal->rx.extent.x-=2; xcal->rx.extent.y-=2;
    rc.topLeft.x=xi; rc.topLeft.y=yi; rc.extent.x=71; rc.extent.y=97;
	WinSetBackColor(xcal->cb[6]); WinEraseRectangle(&rc,0);
	x=rc.topLeft.x; y=rc.topLeft.y; w=rc.extent.x;  h=rc.extent.y;
	PntMarco(x,y,w,h,1,3);
    rc.topLeft.x++; rc.topLeft.y++; rc.extent.x-=2; rc.extent.y=19;
	WinSetBackColor(xcal->cb[8]); WinEraseRectangle(&rc,0);
	SacaTexto(st,5000,8,50);
	for (i=0,w=0;i<StrLen(st);i++) w+=(UInt16)FntCharWidth(st[i]);
	w+=16; x=(rc.extent.x-w)/2; 
	xcal->w1=rc.topLeft.x+x+1; xcal->w2=rc.topLeft.y+5;
	x=xcal->w1-1; y=xcal->w2-1; w=h=10; PntMarco(x,y,w,h,1,3);
    x+=16; y+=2; 
    WinSetTextColor(xcal->cb[10]); WinSetBackColor(xcal->cb[8]); WinDrawChars(st,StrLen(st),x,y);
	x=xcal->w1-3; y=xcal->w2+24; PntMarco(x,y,w,h,1,3);
	x+=35; PntMarco(x,y,w,h,1,3);
	x=xcal->w1-3; y+=14; PntMarco(x,y,w,h,1,3);
	x+=35; PntMarco(x,y,w,h,1,3);
    x=xcal->w1-1; y=xcal->w2+60; PntMarco(x,y,w,h,1,3);
    y+=14; PntMarco(x,y,w,h,1,3);
    x=rc.topLeft.x=xi+74; y=rc.topLeft.y=yi; w=rc.extent.x=76; h=rc.extent.y=97;
	WinSetBackColor(xcal->cb[6]); WinEraseRectangle(&rc,0);
	PntMarco(x,y,w,h,1,3);
    rc.topLeft.x++; rc.topLeft.y++; rc.extent.x-=2; rc.extent.y=19;
	WinSetBackColor(xcal->cb[8]); WinEraseRectangle(&rc,0);
	SacaTexto(st,5000,9,50);
	for (i=0,w=0;i<StrLen(st);i++) w+=(UInt16)FntCharWidth(st[i]);
	w+=16; x=(rc.extent.x-w)/2; xcal->x1=rc.topLeft.x+x+1;
	x=xcal->x1-1; y=xcal->w2-1; w=h=10; PntMarco(x,y,w,h,1,3);
    x+=16; y+=2; WinSetBackColor(xcal->cb[8]); WinDrawChars(st,StrLen(st),x,y);
	xcal->x=82; xcal->y=xcal->rx.topLeft.y+xcal->rx.extent.y+25;
	xcal->pv=false;
	WinSetTextColor(xcal->cb[1]);
	PonValor();
	PintaCalc(0,false,true);
	PintaRed(0);
}
void IniCalc(double v, UInt8 tpc, Boolean ini) {
UInt16         x,y,w,h;
RectangleType  rc,rx;
Char           st[160];
ListType       *lst;
    if (ini) { 
		FrmHideObject(xcal->f,FrmGetObjectIndex(xcal->f,5011));
		FrmHideObject(xcal->f,FrmGetObjectIndex(xcal->f,5012)); 
	}
    IniciaColoresC(ini,&rc,tpc,v); 
    if (xcal->tpc==0) {
    	if (ini) {
			xcal->w1=xcal->w+3; 
			xcal->w2=xcal->w+6; 
			xcal->w3=xcal->w+7; 
    	}
		rc.topLeft.x+=4;  rc.topLeft.y+=4;	rc.extent.x-=8;   rc.extent.y=16;
		WinSetBackColor(xcal->cb[0]); WinEraseRectangle(&rc,0);
		x=rc.topLeft.x; y=rc.topLeft.y; w=rc.extent.x; h=rc.extent.y;
		WinSetForeColor(xcal->cb[1]); 
	           WinDrawLine(x,   y,   x+w, y); 
	           WinDrawLine(x,   y,   x,   y+h-1); 
		WinSetForeColor(xcal->cb[3]); 
	           WinDrawLine(x,   y+h, x+w, y+h); 
	           WinDrawLine(x+w, y+h, x+w, y+1); 
		WinSetForeColor(xcal->cb[0]); 
	           WinDrawLine(x+1,   y+h+1, x+w,   y+h+1); 
	           WinDrawLine(x+w+1, y+h+1, x+w+1, y+2); 
		xcal->rp.topLeft.x=rc.topLeft.x+9; xcal->rp.topLeft.y=rc.topLeft.y+1; 
		xcal->rp.extent.x=rc.extent.x-11;   xcal->rp.extent.y=rc.extent.y-2; 
	    xcal->ra.topLeft.y=xcal->rp.topLeft.y;	
	    xcal->ra.extent.y=xcal->rp.extent.y;	
	   	xcal->py=xcal->rp.topLeft.y+((xcal->rp.extent.y-(FntCharHeight()-2))/2)-1; y-=1; 
	    xcal->x=rc.topLeft.x+1; xcal->y=rc.topLeft.y+rc.extent.y+4;
    }
    else if (xcal->tpc==1) {
    	if (ini) { xcal->vp=IVA; xcal->vc=1; } 
    	rc.topLeft.x+=4; rc.topLeft.y+=2; rc.extent.x-=8;
    	xcal->rx.topLeft.x=rc.topLeft.x; 
    	xcal->rx.topLeft.y=rc.extent.y-23+rc.topLeft.y; 
    	xcal->rx.extent.x=rc.extent.x; xcal->rx.extent.y=18;
		rc.extent.y=xcal->rx.extent.y;
		WinSetBackColor(xcal->cb[6]); WinEraseRectangle(&rc,0);
		WinSetBackColor(xcal->cb[9]); WinEraseRectangle(&xcal->rx,0);
		x=xcal->rx.topLeft.x; y=xcal->rx.topLeft.y; 
		w=xcal->rx.extent.x; h=xcal->rx.extent.y;
		PntMarco(x,y,w,h,1,3);
	    x+=3; y+=3; SacaTexto(st,5000,7,50);      
    	WinSetTextColor(xcal->cb[1]); WinDrawChars(st,StrLen(st),x,y+1);
		x=rc.topLeft.x; y=rc.topLeft.y; w=rc.extent.x; h=rc.extent.y;
		PntMarco(x,y,w,h,1,((PrefGen(1)<=2)?1:0));
	    WinSetBackColor(xcal->cb[6]);
	    x+=3; y+=3; SacaTexto(st,5000,12,50);      
    	WinSetTextColor(xcal->cb[1]); WinDrawChars(st,StrLen(st),x,y+1);
    	x=rc.topLeft.x; y=rc.topLeft.y+h+3; 
    	h=6+(2*FntCharHeight()); w=84-rc.topLeft.x;
        rx.topLeft.x=x; rx.topLeft.y=y; rx.extent.x=w; rx.extent.y=h;
		WinSetBackColor(xcal->cb[7]); WinEraseRectangle(&rx,0);
		PntMarco(x,y,w,h,1,((PrefGen(1)<=2)?1:8));
    	x+=3; y+=3; SacaTexto(st,5000,13,50); 
    	WinDrawChars(st,StrLen(st),x,y); x+=50;
		lst=(ListType *)FrmGetObjectPtr(xcal->f,FrmGetObjectIndex(xcal->f,5011));
		LstSetPosition(lst,x,y);
		StrIToA(xcal->s1,xcal->vp); CtlSetLabel((ControlType *)lst,xcal->s1);
		FrmShowObject(xcal->f,FrmGetObjectIndex(xcal->f,5011));
		lst=(ListType *)FrmGetObjectPtr(xcal->f,FrmGetObjectIndex(xcal->f,5021));
		LstSetPosition(lst,x+10,y-FntCharHeight()); 
		LstSetSelection(lst,xcal->vp-1); 
		LstSetTopItem(lst,((xcal->vp>=5)?xcal->vp-5:0));
		y+=FntCharHeight();
    	x=rc.topLeft.x+3; SacaTexto(st,5000,14,50); 
    	WinDrawChars(st,StrLen(st),x,y); x+=50;
		lst=(ListType *)FrmGetObjectPtr(xcal->f,FrmGetObjectIndex(xcal->f,5012));
		LstSetPosition(lst,x,y);
		StrIToA(xcal->s2,xcal->vc); CtlSetLabel((ControlType *)lst,xcal->s2);
		FrmShowObject(xcal->f,FrmGetObjectIndex(xcal->f,5012));
		lst=(ListType *)FrmGetObjectPtr(xcal->f,FrmGetObjectIndex(xcal->f,5022));
		LstSetPosition(lst,x+10,y-FntCharHeight()); 
		LstSetSelection(lst,xcal->vc-1);
		LstSetTopItem(lst,((xcal->vc>=5)?xcal->vc-5:0));
		y+=FntCharHeight();
    	x=rc.topLeft.x; y+=6; 
        WinSetTextColor(xcal->cb[1]); h=3+(2*FntCharHeight()); w=84-rc.topLeft.x;
        rx.topLeft.x=rc.topLeft.x; rx.topLeft.y=y; rx.extent.x=w; rx.extent.y=h;
		WinSetBackColor(xcal->cb[0]); WinEraseRectangle(&rx,0);
		PntMarco(x,y,w,h,1,3);
		y+=2; x+=3; xcal->xp=x; xcal->yp=y;
		WinSetTextColor(xcal->cb[8]);
        SacaTexto(st,5000,15,50); WinDrawChars(st,StrLen(st),x,y); y+=FntCharHeight(); 
        SacaTexto(st,5000,16,50); WinDrawChars(st,StrLen(st),x,y);
        WinSetTextColor(xcal->cb[1]);
		rc.topLeft.x+=90; rc.topLeft.y+=2; rc.extent.x-=92; rc.extent.y=14;
		xcal->rx.topLeft.x+=90; xcal->rx.topLeft.y+=2; 
		xcal->rx.extent.x-=92;  xcal->rx.extent.y=14;
		WinSetBackColor(xcal->cb[0]); WinEraseRectangle(&rc,0);
		WinSetBackColor(xcal->cb[9]); WinEraseRectangle(&xcal->rx,0);
		x=xcal->rx.topLeft.x; y=xcal->rx.topLeft.y; 
		w=xcal->rx.extent.x;  h=xcal->rx.extent.y;
		PntMarco(x,y,w,h,((PrefGen(1)<=2)?1:8),3);
		x=rc.topLeft.x; y=rc.topLeft.y; w=rc.extent.x; h=rc.extent.y;
		PntMarco(x,y,w,h,1,3);
		xcal->rp.topLeft.x=rc.topLeft.x+1;  xcal->rp.topLeft.y=rc.topLeft.y+1; 
		xcal->rp.extent.x=rc.extent.x-2;    xcal->rp.extent.y=rc.extent.y-2; 
	    xcal->ra.topLeft.y=xcal->rp.topLeft.y;	
	    xcal->ra.extent.y=xcal->rp.extent.y;	
	   	xcal->py=xcal->rp.topLeft.y+((xcal->rp.extent.y-(FntCharHeight()-2))/2)-1; y-=1; 
		xcal->x=88; xcal->y=rc.topLeft.y+18;
		WinSetBackColor(xcal->cb[0]);
		xcal->rx.topLeft.x++; xcal->rx.topLeft.y++;
		xcal->rx.extent.x-=2; xcal->rx.extent.y-=2;
    }
	PonValor();
	PintaCalc(0,false,true);
	SacaTexto(xcal->s3,5000,(xcal->tpc==0)?11:17,25);
	CtlSetLabel(GetObjPtr(xcal->f,CalcOper),xcal->s3);
	CtlShowControl(FrmGetObjectPtr(xcal->f, FrmGetObjectIndex(xcal->f,CalcCancela)));
	CtlShowControl(FrmGetObjectPtr(xcal->f, FrmGetObjectIndex(xcal->f,CalcAcepta)));
	CtlShowControl(FrmGetObjectPtr(xcal->f, FrmGetObjectIndex(xcal->f,CalcAyuda)));
	CtlShowControl(FrmGetObjectPtr(xcal->f, FrmGetObjectIndex(xcal->f,CalcOper)));
}
void IniciaCalc(UInt8 tp, FormType *fr, double *v) {
    WinPushDrawState();
	mcal=MemHandleNew(sizeof(Calc));
	xcal=(Calc *)MemHandleLock(mcal);
	xcal->fr=fr; xcal->re=v; xcal->v=*v; xcal->tpc=tp;
 	FrmPopupForm(FCalcula);
}
void FinCalc(Boolean baj) { 
double v;
	WinPopDrawState(); 
	if (baj) { 	
		v=AdblX(xcal->st); 
        if (xcal->tpc==1) v=v*(double)((double)1+(double)((double)xcal->vp/(double)100))/(double)xcal->vc; 
       	*(xcal->re)=v;
	}
   	FrmUpdateForm(FrmGetFormId(xcal->fr),70);
	MemHandleUnlock(mcal); MemHandleFree(mcal); 
	FrmReturnToForm(0);
}
// Calculadora general y de propinas
void RegVal(Int16 v) {
	StrIToA(xcal->s4,v+1); WinSetBackColor(xcal->cb[7]);
	CtlSetLabel(FrmGetObjectPtr(FrmGetActiveForm(),FrmGetObjectIndex(FrmGetActiveForm(),5011)),xcal->s4);
   	xcal->vp=v+1; 
   	if (PrefGen(1)==1) { xcal->v=Adbl(xcal->st); IniCalc(xcal->v,1,false); }
   	else PonDatos(); 
}
Boolean Calcula(EventType* pEvent) {
UInt16 	tec;
Int16   v;
	switch (pEvent->eType) {
		case frmOpenEvent:
			FrmDrawForm(FrmGetActiveForm());
    		xcal->f=FrmGetActiveForm();
			IniCalc(xcal->v,xcal->tpc,true);
			xcal->pd=false;
			return true;
		case frmCloseEvent:
		    FinCalc(false);
		    return true;
		case ctlSelectEvent:
		    switch(pEvent->data.ctlSelect.controlID) { 
		    case CalcAyuda:   //RutAyuErr(((opg==1)?ACalcGeneral:ACalcPropina));
				 			  return true;		    
		    case CalcCancela: if (xcal->tpc==2) IniCalc(xcal->v,1,false);
			        		  else FinCalc(false); return true;
	        case CalcAcepta:  FinCalc(true); return true;
	        case CalcOper  :  IniCalc(xcal->v,(xcal->tpc==1)?0:1,true); return true;
			}
			break;
        case penDownEvent:
			xcal->pd=true;
            tec=EnTecladoC(pEvent->screenX,pEvent->screenY);
            if (tec!=0 && !(xcal->tpc==2 && xcal->w3!=2)) { PintaCalc(tec,true,true); return true; }
			xcal->pd=false;
            if (xcal->tpc==2) return EnControlProp(tec,pEvent->screenX,pEvent->screenY);
            break; 
        case penUpEvent:
        	if (!xcal->pd) return true;
			xcal->pd=false;
            tec=EnTecladoC(pEvent->screenX,pEvent->screenY);
            if (tec!=0 && tec==xcal->tec && !(xcal->tpc==2 && xcal->w3!=2)) { OperaTecladoC(); return true; }
            else if (xcal->tec!=0 && !(xcal->tpc==2 && xcal->w3!=2)) { PintaCalc(xcal->tec,false,true); return true; }
            break;
        case penMoveEvent:
        	if (!xcal->pd) return true;
            if (xcal->tec!=0) {
            	tec=EnTecladoC(pEvent->screenX,pEvent->screenY);
            	if (tec!=xcal->tec && !(xcal->tpc==2 && xcal->w3!=2)) PintaCalc(xcal->tec,false,true);
            	return true;
            }
            break;
        case ctlEnterEvent:
        	if (pEvent->data.ctlEnter.controlID==5011) {
        	   v=LstPopupList(FrmGetObjectPtr(FrmGetActiveForm(),FrmGetObjectIndex(FrmGetActiveForm(),5021)));
        	   if (v!=-1) RegVal(v);
        	   return true;
        	}
        	if (pEvent->data.ctlEnter.controlID==5012) {
        	   v=LstPopupList(FrmGetObjectPtr(FrmGetActiveForm(),FrmGetObjectIndex(FrmGetActiveForm(),5022)));
        	   if (v!=-1) RegVal(v);
        	   return true;
        	}
        	break;
        default: break;
	}
	return false;
}