// Copyright (c) 1993-2005 "Компания БЭСТ". Все права сохраняются.

#include "inkey.ch"
#include "s_public.ch"

STATIC aCoord:={}
STATIC strout     := ' ',;
       nTCalk     := 01,      ;
       nLCalk     := 00,      ;
       nMax       := 1,       ;
       aArrayReg  := {'0','0','0','0','0','0','0','0'},       ;
       aMmag_Colr:= {'W+/G','N/G','GR+/N','GR+/G','W+/B','BG+/G'}, ;
       nW

PROCEDURE MAGCALC()
LOCAL mRow,mCol
  LOCAL aSet,;
        cTrapAny := TrapAnyKey(),;
        aKey := SaveSetKey(),;
        i:=1, oGet, nDec := 2,        ;
        NUMARR:=1, val_exp:=0,znak_exp:='',;
        FLAG_ZNAK,keyreturn


  strout := PADL( strout, 17 )

  nW := WSELECT()
  WSELECT(0)
  aSet:=SaveSet()
  WSELECT(nW)
  nW := NIL

  MAGCOLOR(1)
  IF (nW := OpenScreen( nMax )) < 0
    TrapAnyKey(cTrapAny)
    WSELECT(0)
    RestSet(aSet)
    RestSetKey(aKey)
    WSELECT(nW)
    RETURN
  EndIF

DO WHILE NUMARR <> 0
   
   @ 1+NUMARR, 20 SAY "-"  COLOR aMmag_Colr[6]
   SETPOS(1,18)
   keyreturn := InKey(0,INKEY_KEYBOARD+INKEY_LDOWN)

   IF LASTKEY() = K_LBUTTONDOWN
      IF (keyreturn:=GetKeyReturn(mRow()+1,mCol()))=0
         LOOP
      ENDIF

   ENDIF


   keyreturn:=CHR(keyreturn)

   FLAG_ZNAK := .T.
   DO CASE


      CASE keyreturn $ CHR(K_UP)+CHR(K_DOWN)
        @ 1+NUMARR, 20 SAY " " COLOR aMmag_Colr[6]
        IF keyreturn == CHR(K_UP)
          NUMARR--
          IF( NUMARR< 1, NUMARR := 8, )
        ELSE
          NUMARR++
          IF( NUMARR>8, NUMARR := 1, )
        ENDIF
        IF( !EMPTY(znak_exp), FLAG_ZNAK := .F., )

      CASE keyreturn $ CHR(42)+CHR(43)+CHR(45)+CHR(47)
                         *       +       -       /
          val_exp := ANL_OPER(znak_exp,val_exp)
          znak_exp=keyreturn
          MAGCOLOR(2) //2
          @ 1,1 SAY znak_exp
          MAGCOLOR(3)//3
          @ 1,2 SAY strout
          FLAG_ZNAK=.F.
          strout := ''

      CASE keyreturn $ CHR(61)+chr(13)  && нажали "=" или Enter
          val_exp := ANL_OPER(znak_exp,val_exp)
          znak_exp=" "

      CASE keyreturn = CHR(46).OR.keyreturn = CHR(44)  && нажали . или ,
          IF keyreturn = CHR(44)
             keyreturn := CHR(46)
          ENDIF
          IIF("." $ strout,,strout:=ALLTRIM(strout)+keyreturn)

      CASE keyreturn$"0123456789"  && цифра
          strout := ALLTRIM(strout)+keyreturn

      CASE keyreturn  = CHR(4)
          aArrayReg[NUMARR] := strout
          @ 1+NUMARR,24 SAY PADL(aArrayReg[NUMARR],17) COLOR aMmag_Colr[4]

      CASE keyreturn = CHR(19)
          strout := aArrayReg[NUMARR]

      CASE  keyreturn = CHR(9)
        oGet := GetActive()
        If ( oGet != NIL .AND. oGet:type="N" .AND. val(strout)<>0 )
           If (At('.',oGet:Buffer) == 0) && Значит число целое
              If Len( AllTrim(Str(Round(Val(strout),0),13,0)) ) <= Len(oGet:buffer)
                 oGet:VarPut( Round(Val(strout),0) )
                 oGet:changed:=.T.
              EndIF
           Else
              If Len( AllTrim(Str(Val(strout),17,Len(oGet:buffer)-oGet:decPos)) ) <= Len(oGet:buffer)
                 oGet:VarPut(Val(strout) )
                 oGet:changed := .T.
              EndIF
           EndIf
           strout:=''
           NUMARR=0
           LOOP
        EndIF

      CASE keyreturn = CHR(32)
        strout := ''

      CASE  keyreturn = CHR(8)
        strout := SUBSTR(ALLTRIM(strout),1,len(ALLTRIM(strout))-1)

      CASE  keyreturn = CHR(10)  && Загрузка числа из поля K_CTRL_RET
        oGet := GetActive()
        If ( oGet != NIL )
            If ( oGet:type="N" )
                strout:= ( oGet:Buffer )
            EndIf
        EndIf

      CASE  keyreturn = CHR(18)
        nMax:=2
        OpenScreen(nMax)   && Уменьшение калькулятора

      CASE  keyreturn = CHR(3)
        nMax:=1
        OpenScreen(nMax)   && Увеличение калькулятора

      CASE  keyreturn = CHR( K_ESC )
        EXIT

   ENDCASE

   strout := PADL( strout, 17 )
   IF FLAG_ZNAK
      @ 1,1 SAY znak_exp COLOR aMmag_Colr[2]
      @ 1,2 SAY strout   COLOR aMmag_Colr[3]
   ENDIF

ENDDO

* Глобальные переменные запомним

nTCalk    := WROW()
nLCalk    := WCOL()

WCLOSE()
WSELECT(0)
RestSet(aSet)
WSELECT(nW)
RestSetKey(aKey)
TrapAnyKey(cTrapAny)
RETURN

*
FUNCTION OpenScreen( Max )
  If nW != NIL
    nTCalk    := WROW()
    nLCalk    := WCOL()
    WCLOSE()
    WSELECT(nW)
  EndIF
  MAGCOLOR(1) //1
  nW := NewWindow(nTCalk, nLCalk, If(Max==1,18,11), 43,"",2,.T.,,MAGCOLOR(1))    //1
  ScreenCalk( Max )

RETURN nW

*
FUNCTION ScreenCalk( Max )

  LOCAL i,;
        klav := "789+456-123/0.=*"
MAGCOLOR(1) // 1
@ 00, 19 SAY '╤'
@ 01, 19  TO  09, 19
@ 2,1 SAY "──────────────────"
MAGCOLOR (2) //2
@ 1, 26 SAY "Регистры"
FOR i=1 to 8
  MAGCOLOR (2) //2
  @ 1+i,21 SAY str(i,1)
  MAGCOLOR (4)  //4
  @ 1+i,24 SAY PADL(aArrayReg[i],17)
NEXT
MAGCOLOR(5)//5
aCoord:={}
FOR i:=1 to 16
  @ 3+2*INT((i-1)/4), 3+4*((i-1)%4) SAY  " "+substr(klav,i,1)+" "
  AADD(aCoord,{WRow()+3+2*INT((i-1)/4),WCol()+3+4*((i-1)%4),substr(klav,i,1)})
NEXT
MAGCOLOR(3)//3
@ 1,2 SAY strout

If (Max==1)
   MAGCOLOR(1)//1
   @ 10, 00 SAY '╟──────────────────┴──────────────────────╢'
   @ 11, 8 SAY "Ввод(=)        Сброс        Выход"
   @ 12,16 SAY "Перемещение по регистрам"
   @ 13,16 SAY "Взять/занести в регистр"
   @ 14,16 SAY "Занести в поле ввода"
   @ 15,16 SAY "Взять из поля ввода"
   @ 16,16 SAY "Размер калькулятора"

   MAGCOLOR(6)//6
   @ 11,  2 SAY "Enter:"
   @ 11, 16 SAY "Пробел:"
   @ 11, 32 SAY "Esc:"
   @ 12,  2 SAY "Вверх/вниз:"
   @ 13,  2 SAY "Влево/Вправо:"
   @ 14,  2 SAY "TAB:"
   @ 15,  2 SAY "Ctrl-Enter:"
   @ 16,  2 SAY "PgDn/PgUp:"

EndIF
RETURN NIL

*
*===============================================================
*   Функция анализа знаков (операций)
*
FUNCTION ANL_OPER( z_exp, v_exp)
  LOCAL nDec
  IF     z_exp="+"
      v_exp := v_exp+VAL(Strout)
  ELSEIF z_exp="-"
    v_exp := v_exp-VAL(Strout)
  ELSEIF z_exp="*"
    v_exp := v_exp*IIF(EMPTY(alltrim(Strout)),1,VAL(Strout))
  ELSEIF z_exp="/"
    v_exp :=  ZERO(v_exp,IIF(EMPTY(alltrim(Strout)),1,VAL(Strout)))
  ELSE
    v_exp := VAL(Strout)
  ENDIF
  nDec := 16 - LEN(ALLTRIM(STR(v_exp,17,0)))
  Strout := STR(v_exp,17,nDec)
  IF nDec > 0
    strout:= PADL(REMRIGHT(REMRIGHT(strout,48),46),17)
  ENDIF

RETURN ( v_Exp )

STATIC FUNCTION MAGCOLOR( cl1 )
RETURN SETCOLOR(aMmag_Colr[cl1])

STATIC FUNCTION ZERO(ZNUM1, ZNUM2)
RETURN IF( ZNUM2 <> 0, (ZNUM1/ZNUM2), 0 )

STATIC FUNCTION GetKeyReturn(mRow,mCol)
LOCAL nPos:=ASCAN(aCoord,{|x|mRow==x[1].AND.mCol>=x[2].AND.mCol<=x[2]+3})

IF nPos>0
   RETURN ASC(aCoord[nPos,3])
ENDIF
IF nMax=1
   DO CASE
   CASE mRow==12 .AND. mCol>=1.AND.mCol<=14
   RETURN K_RETURN

   CASE mRow==12 .AND. mCol>=15.AND.mCol<=30
   RETURN ASC(" ")

   CASE mRow==12 .AND. mCol>=31.AND.mCol<=39
   RETURN K_ESC


   CASE mRow==13 .AND. mCol>=1.AND.mCol<=5
   RETURN K_UP

   CASE mRow==13 .AND. mCol>=6.AND.mCol<=15
   RETURN K_DOWN

   CASE mRow==14 .AND. mCol>=1.AND.mCol<=7
   RETURN K_LEFT

   CASE mRow==14 .AND. mCol>=8.AND.mCol<=15
   RETURN K_RIGHT

   CASE mRow==15 .AND. mCol>=1.AND.mCol<=15
   RETURN K_TAB

   CASE mRow==16 .AND. mCol>=1.AND.mCol<=15
   RETURN K_CTRL_RETURN

   CASE mRow==17 .AND. mCol>=1.AND.mCol<=15
   RETURN K_PGUP


   ENDCASE
ENDIF
RETURN 0






