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

#define DEBUG "Для внутреннего использования"

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

STATIC cItMetF1:="00", cItMetF2:="01"  //
STATIC aColor
STATIC aPalitra := { "W+/W","N/W", "BG+/W", "GR+/W", "G+/W", "R+/W",;
                     "RB+/W", "N+/W", "B+/W", "GR/W" }
STATIC nMenu := 1

FIELD N_RAZD, TEXT_MET IN HELP

// Функция связи
// Присвоение новых значений
PROCEDURE LOAD_HELP( cMetF1, cMetF2 )
  cItMetF1 := IF( cMetF1 == NIL, cItMetF1, cMetF1 )
  cItMetF2 := IF( cMetF2 == NIL, cItMetF1, cMetF2 )
RETURN

// Возврат текущих хначений
FUNCTION SAVE_HELP()
RETURN ( { cItMetF1, cItMetF2 } )


FUNCTION MY_HELP ( cFile, cColor, aNewPalitra )


  LOCAL nOldWindow := WSELECT(  )  // Физический Экран
  LOCAL nTop := 03, nLeft := 06, aSet , aSetKeys := SaveSetKey()
  LOCAL nTek_razd := 1, nHelp := 1, aMas_Txt
  LOCAL aMenu_oglav, i
  LOCAL nOldArea := SELECT()
  LOCAL lCursor:=SETCURSOR(0),;
        lRec_Yes := _REC_YES

  _REC_YES  := .T.
  SETKEY( K_F1,         NIL ) // Обнулим а востановят за нас
  SETKEY( LASTKEY(),    NIL )

  WSELECT( 0 )
  aSet := SaveSet()


  aColor := LineToArray( IF( cColor==NIL, "N/W,W+/N,W+/W", cColor ), ",")
  //aColor[1] - текст/фон
  //aColor[2] - выдел.меню/выдел.фон
  //aColor[3] - заголовки/фон

  IF ValType( aNewPalitra ) == "A"
    aPalitra := aNewPalitra
  ENDIF

  BEGIN SEQUENCE

    IF !FILE( cFile+".DBF" ) .OR. !NetUse( "HELP", cFile/*, cFile*/ )
      SAYERROR( "Файл 'ПОДСКАЗОК': "+cFile+".DBF не найден!")
      BREAK(1)
    ENDIF
//    nTek_razd := UPPER(ALLTRIM(IF( LASTKEY() == K_F1, cItMetF1, cItMetF2 )))
    cItMetF1 := nTek_razd := IF( LASTKEY()<>K_F1, '_','')+UPPER(ALLTRIM(M->Help_Code))       // Только для этой версии
    *.........поиск нужной записи
    If !dbSeek( PADR( nTek_razd, 8 ) )
       IF YesOrNo( "Добавить раздел '"+;
                   nTek_razd +"' ?", .T.)
         IF PutNetAdd( { nTek_razd, "|2Раздел: |3"+nTek_razd } )
            UNLOCK
            IF !dbSEEK( SPACE(8) )
              PutNetAdd( { "", "" } )
              UNLOCK
            ENDIF
            IF RecLock()
              TEXT_MET += IF(RIGHT(TEXT_MET,2) = CHR(13)+CHR(10),"",CHR(13)+CHR(10))+PADR(nTek_razd,8)+" Раздел: "+nTek_razd+CHR(13)+CHR(10)
              UNLOCK
            ENDIF
         ENDIF
       ELSE
         BREAK(1)
       ENDIF
    ENDIF

    //...Формирование меню оглавления
    aMenu_oglav := Menu_oglav()
    nTek_razd := ASCAN(aMenu_oglav[1], nTek_razd )
    IF nTek_razd == 0
      nTek_Razd := cItMetF1
      IF !dbSEEK( SPACE(8) )
        PutNetAdd( { "", "" } )
        UNLOCK
      ENDIF
      IF RecLock()
        TEXT_MET += IF(RIGHT(TEXT_MET,2) = CHR(13)+CHR(10),"",CHR(13)+CHR(10))+PADR(nTek_razd,8)+" Раздел: "+nTek_razd+CHR(13)+CHR(10)
        UNLOCK
      ENDIF
      aMenu_oglav := Menu_oglav()
      nTek_razd := ASCAN(aMenu_oglav[1], nTek_razd )
    ENDIF

    SETCOLOR( aColor[1] )
    SHADOWBox(" Помощь "+cItMetF1+ ' ', nTop, nLeft+1, nTop+19, nLeft+66 ) // Полутень
    @ nTop+02, nLeft+01 Say "╟"+REPLICATE("─",64)+"╢"        //  ╢182  ╟199
    @ nTop+17, nLeft+01 Say "╟"+REPLICATE("─",64)+"╢"
    @ nTop+18, nLeft+66 Say CHR(29)  Color aColor[2]
#ifndef DEBUG
    ScrTitul( 24,"Esc: Выход" )
#else
    ScrTitul( 24,"Shift-F1,F2:Редак., Ctrl-F1:Считать из файла Alt-F1:Оглавление F9:Печать Esc:Выход" )
#endif

    *........основной цикл работы
    Do while .T.

      dbSeek( UPPER(PADR( ALLTRIM(aMenu_oglav[1][nTek_razd]  ),8 )) )
      *.... Чтение строки методики в массив
      aMas_Txt := STR_TO_ARRAY( TEXT_MET )
      *...Просмотр массива с текстом раздела методики
      @ 06, 08 Clear to 19, 71
      nHelp := REV_TXT_MET( 6, 8, 19, 71, aMas_txt, ALLTRIM(aMenu_oglav[2][nTek_razd]) )

      Do Case
          Case nHelp == 6
              aMenu_oglav := Menu_oglav()

          Case nHelp == 1   // переход к следующему разделу
               If nTek_razd < LEN(aMenu_oglav[1])
                 nTek_razd++
               Else
                 ? CHR(7)   // Beep
                 SAYAndWait("   Раздел последний !  ")
               EndIf

          Case nHelp == 2   // переход к предыдущему разделу
               If nTek_razd > 1
                 nTek_razd--
               Else
                 ? CHR(7)   // Beep
                 SAYAndWait("   Раздел первый !  ")
               EndIf

          Case nHelp == 3   // выбор из меню оглавления

               @ 04, 08 Clear to 04, 71
               @ 06, 08 Clear to 19, 71
               @ 21, 08 Clear to 21, 71
               @ 04, 23 Say "Разделы методики работы c системой" ;
                          Color aColor[3]

               For i := 6 to 19
                   @ i, 72 Say CHR(176)   //░
               Next

               *......высветить горизонт.меню оглавления
               PROMPT( 2 )
               nMenu := 1
               SETCOLOR( aColor[1] +","+ aColor[2] )
               nTek_razd := ACHOICE(6,8,19,71,aMenu_oglav[2],.T.,"OGL_USF",;
                                nTek_razd )
               @ 04, 08 Clear to 04, 71
               @ 06, 08 Clear to 19, 71
               @ 21, 08 Clear to 21, 71
               nMenu := 3
               If nTek_razd == 0  //если ESC в ACHOICE()
                 Exit
               EndIf
               SETLASTKEY(0)

          Case nHelp == 4   // возврат
               Exit
      EndCase
    EndDo

  END SEQUENCE

  IF SELECT("HELP") > 0
    HELP->( dbCloseArea() )
  ENDIF

  *..........выход
  SELECT( nOldArea )
  RestSet(aSet)
  RestSetKey(aSetKeys)
  WSELECT( nOldWindow )
  Clear TypeAhead
  SETCURSOR(lCursor)
  _REC_YES :=lRec_Yes
RETURN (1)


*****************************************
*    Promptы  горизонтального меню      *
*****************************************
STATIC Procedure PROMPT( nPrompt )
  LOCAL cOldColor := SETCOLOR( aColor[3] )
  LOCAL nCol := 09, aMenu := { 9, 24, 39, 54 }
  @ 21, 09 SAY SPACE( 58 )
  IF nPrompt == 1
    @ 21, 09 SAY "[ Следующая  ]"
    @ 21, 24 SAY "[ Предыдущая ]"
    @ 21, 39 SAY "[ Оглавление ]"
    @ 21, 54 SAY "[ Выход      ]"
    COLORWIN( 21, aMenu[nMenu], 21, aMenu[nMenu]+13, aColor[2] )
//          1         2         3         4         5         6
//01234567890123456789012345678901234567890123456789012345678901234567890
//       [ Следующая  ] [ Предыдущая ] [ Оглавление ] [ Возвpат    ]
  ELSE
    @ 21, 20 SAY "[  Просмотр  ]"
    @ 21, 40 SAY "[  Выход     ]"
    nCol := 20
    COLORWIN( 21, nCol, 21, nCol+13, aColor[2] )
  ENDIF
  SETCOLOR( cOldColor )
Return

******************************************************************
* функция пользователя для ACHOICE() выбора из оглавления в HELP *
******************************************************************
Function OGL_USF( nMode, nI, nRow )
  LOCAL nLaskey := LASTKEY()

  COLORWIN( 21, 20*nMenu, 21, 20*nMenu+13, aColor[3] )

  Do Case
     Case nLaskey == K_RIGHT  .OR. nLaskey == K_LEFT   // Вправо
       nMenu := IF( nMenu == 1, 2, 1 )

     Case nLaskey == K_ESC    //Esc
       Return ( 0 )

     Case nLaskey == K_ENTER    //Return
       Return ( IF( nMenu == 1, 1, 0 ) )
  EndCase

  COLORWIN( 21, 20*nMenu, 21, 20*nMenu+13, aColor[2] )
Return ( 2 )
*End Of OGL_USF()

*******************************************************************
*  Просмотр текстового массива  методики с цветом в окне дисплея  *
*******************************************************************
* Прараметры:y1,x1,y2,x2 - координаты окна для просмотра;
*                 mas  - имя  массива;
STATIC FUNCTION REV_TXT_MET( nY1, nX1, nY2, nX2, aMas, cRazd  )
  LOCAL nLen := LEN( aMas ), i, nStr := 1, lRepeat := .T.
  LOCAL nKey, aMenu := { 9, 24, 39, 54 }, nRet := 4, nPos:=1, j
  LOCAL nWith
  FIELD N_RAZD, TEXT_MET IN HELP


  *...пересмотр границ окна
  nY2 := MIN( nY2, (nY1+nLen-1) )
  nWith := nY2 - nY1

  For i := 6 to 19
    @ i, 72 Say CHR(176)   //░
  Next

  If nLen  > 14
    SETCOLOR( aColor[2] )
    @ 06, 72 Say CHR(24)
    @ 19, 72 Say CHR(25)
    SETCOLOR( aColor[1] )
    nPos := nY1
  EndIf

  SETCOLOR( aColor[3] )
  @ 04, 08 Clear to 04, 71
  @ 04, 09 Say "Раздел: " + PADR( cRazd, 50 )
  SETCOLOR( aColor[1] )

  PROMPT( 1 )
  //nMenu := 1

  Do while .T.
    If nLen > 14
      *...Восстановление старого маркера
      RES_MARKER( nPos )
      *...вывод маркера
      If nStr == 1
         nPos := nY1  //позиция маркера по вертикали
      Else
         nPos := nY1 +INT((nStr)/(nLen-13)*13)
      EndIf
      @ nPos, 72 Say "▓" Color "15/0"
    EndIf
    j:= nStr
       IF lRepeat
         @ nY1, nX1 Clear to nY2, nX2
         For i := nY1 to nY2
           SAY_CLR_STRING( i, nX1, aMas[j], aPalitra )
           IF( j < LEN(aMas), j++, i:=nY2 )
         Next
       ENDIF
   *...анализ нажатой клавиши
   nKey := INKEYTRAP( 0 )

   lRepeat := .F.
   Do Case
      Case nKey == K_ENTER .AND. nMenu > 2
        nRet := nMenu
        EXIT

      Case nKey == K_ESC
        nRet := 4
        EXIT

#ifdef DEBUG         // Только для Ввода информации
      Case nKey == K_ALT_F1 .AND. dbSEEK( SPACE(8) )
        HelpEdit(TEXT_MET)
        Menu_oglav()
        nMenu := 3
        nRet := 6
        EXIT

      Case nKey == K_SH_F1
        HelpEdit(TEXT_MET)
        nRet := 5
        EXIT

      Case nKey == K_SH_F2
        HelpKey()
        nRet := 5
        EXIT

      Case nKey == K_CTRL_F1
        HelpRead()
        nRet := 5
        EXIT

      Case nKey == K_F9
        HelpPrint()
        nRet := 5
        EXIT
#endif

      Case nKey == K_LEFT .OR. nKey == K_RIGHT
        COLORWIN( 21, aMenu[nMenu], 21, aMenu[nMenu]+13, aColor[3] )
        nMenu += IF( nKey == K_LEFT, -1, 1 )
        nMenu := IF( nMenu == 0, 4, IF( nMenu == 5, 1, nMenu ) )
        COLORWIN( 21, aMenu[nMenu], 21, aMenu[nMenu]+13, aColor[2] )

      Case nKey == K_UP      //{UP}
        If nStr > 1  //Если строка массива не первая
           SCROLL( nY1, nX1, nY2, nX2, -1 )
           nStr--
           SAY_CLR_STRING( nY1, nX1, aMas[nStr], aPalitra )
        EndIf

     Case nKey == K_DOWN   //{DOWN}
       If nStr < nLen - nWith  //Если страница не последняя
          SCROLL( nY1, nX1, nY2, nX2, 1 )
          nStr++
          SAY_CLR_STRING( nY2, nX1, aMas[nStr+nWith], aPalitra )
       EndIf

     Case nKey == K_PGUP .OR. ;    //PgUp
           (nKey == K_ENTER .AND. nMenu == 2)
       IF nStr > nWith
          nStr -= nWith
         lRepeat := .T.
       Else
         If nStr != 1
           nStr -= nWith + 1
           lRepeat := .T.
         EndIf
       EndIf
       IF nStr<1
          nStr:=1
       ENDIF

     Case nKey == K_PGDN .OR. ; //PgDn
           (nKey == K_ENTER .AND. nMenu == 1)
       IF nStr <  nLen - 2*nWith
         nStr +=nWith
         lRepeat := .T.
       Else
         If nStr < nLen - nWith
            nStr := nLen - nWith
            lRepeat := .T.
         EndIf
       EndIf
    EndCase
  EndDo
Return ( nRet )
*End of  REV_TXT_MET()

*********************************************
*  Восстановление на экране старого маркера *
*********************************************
STATIC Procedure RES_MARKER ( nPos )
  Do Case
     Case nPos == 6    //1-я строка окна
       @ nPos, 72 Say "" Color "15/0"
     Case nPos == 19    //последняя строка
       @ nPos, 72 Say "" Color "15/0"
     Otherwise
       @ nPos, 72 Say "░"
  EndCase
Return
*End Of RES_MARKER()

**********************************************
*      Вывод строки с изменением цвета       *
**********************************************
*Обращение: SAY_CLR_STRING(y,x,string)
*Параметры: y,x - координаты начала вывода
*        string - текстовая строка вида:
*                 <текст>|n<текст>|n<текст>....  ,
*                 где |n - переключатель цветовой палитры
*                          n = индекс в массиве цветовых палитр
*                              CLR_PALETTE ;  1 <= n <= 9  .
*Предварительно: необходимо определить массив CLR_PALETTE,
*                например,  clr_palette[2]
*                           clr_palette[1] = "15/3"
*                           clr_palette[2] = "14/3"
*Примечание: Переключатель палитры действует только до конца строки !

STATIC Procedure SAY_CLR_STRING( nY, nX, cString, aClr_palette)
	LOCAL nPoz_switch 	&&позиция переключателя палитры
  LOCAL cOld_clr :=  SETCOLOR(), nColor := 2

	Do While .T.
    nPoz_switch := AT('|', cString)
    If nPoz_switch == 0
      @ nY, nX Say cString
			Exit
		EndIf
    @ nY, nX Say LEFT( cString, nPoz_switch - 1)        //  + "  "  Уберем спец символы
    nColor := VAL(SUBSTR(cString,nPoz_switch+1,1))+1
    SETCOLOR( aClr_palette[IF( nColor<1 .OR. nColor>10, 2, nColor)])
		*...Усечение слева
    cString := SUBSTR( cstring, nPoz_switch+2)
    nX += nPoz_switch - 1    // + 1 - Цветовые атрибуты на " "
                             // - 1 - Цветовые атрибуты в длине не учитываются
	EndDo
  SETCOLOR( cOld_clr )
Return
*End Of SAY_CLR_STRING()

#ifdef DEBUG         // Только для Ввода информации
STATIC PROCEDURE HelpRead()
  LOCAL cFile:=SPACE(20), cText_Met
  IF GetAnyThing( @cFile, "XXXXXXXXXXXXXXXXXXXXXX","Имя файла: ",10,10,COL_BROWSE)
    cFile := ALLTRIM(cFile)
    IF FILE( cFile )
      cText_Met := MEMOREAD( cFile )
      HelpEdit( @cText_Met )
    ELSE
      SayError( "Файл не найден: "+ cFile )
    ENDIF
  ENDIF
RETURN

STATIC PROCEDURE HelpEdit(cText_Met)
  LOCAL nY1:=5, nY2:=20, nX1:=7, nX2:=72
  LOCAL aSet := SaveSet()
  FIELD TEXT_MET IN HELP
  SETCOLOR( aColor[3])
  SHADOWBox(" Редактирование ", nY1, nX1, nY2, nX2 )
  SET CURSOR ON
  SETCOLOR( aColor[1] )
  cTEXT_MET := MEMOEDIT( cTEXT_MET, nY1+1, nX1+1, nY2-1, nX2-1, .T.)
  IF LASTKEY()<> K_ESC .AND. RecLock()
    TEXT_MET := ATREPL( CHR(141)+CHR(10), cText_Met, CHR(13)+CHR(10) )
  ENDIF
  SET CURSOR OFF
  RestSet( aSet )
RETURN

STATIC PROCEDURE HelpPrint()
  LOCAL cTmpFile := TEMPFILE( _TMP_DIR, 'HLP' )
  FIELD TEXT_MET IN HELP
  MEMOWRIT( cTmpFile, TEXT_MET )
  VIEW( cTmpFile )
RETURN

#endif         // Только для Ввода информации

FUNCTION STR_TO_ARRAY(cText, nWidth )
  LOCAL cLine, aText := {}, i, nLen
  TOKENINIT(@cText, CHR(13)+CHR(10), 2)  // делим на строки
  DO WHILE !TOKENEND()
    cLine := TOKENNEXT(@cText)
    IF cLine!=NIL
       IF ValType(nWidth)=='N' .AND. LEN( cLine ) > nWidth
          nLen := MLCOUNT( cLine, nWidth )
          For i := 1 To nLen
            AADD( aText, MEMOLINE( cLine, nWidth, i) )
          Next
       ELSE
         AADD( aText, cLine )
       ENDIF
    ENDIF
  ENDDO
RETURN (aText)

STATIC FUNCTION Menu_oglav()
  LOCAL aMenu_Oglav[2]
  IF dbSEEK( SPACE(8) )
      *.... Чтение строки оглавления в массив
      aMenu_oglav[1] :=   STR_TO_ARRAY( TEXT_MET )
      aMenu_oglav[2] := {}
      aEVAL( aMenu_oglav[1], {|x,i| aMenu_oglav[1][i]:= UPPER(RTRIM(LEFT(x,8))),;
                                    AADD( aMenu_oglav[2], RTRIM(SUBSTR(x,9)) ) } )
  ENDIF
RETURN ( aMenu_oglav )
//-------------------------------------------------------------------------//
                  STATIC PROCEDURE HelpKey()
//-------------------------------------------------------------------------//
LOCAL cDefName := N_RAZD
LOCAL sWin, sColor
LOCAL x := 4
PRIVATE GetList := {}

 sWin:=SaveScreen(x, 0, x+3, MAXCOL())
 sColor:=SETCOLOR(COL_INPUT)
 ShadowBox('', x, 10, x+2, 70, COL_INPUT)
 cDefName:=PADR(cDefName,45)
 @ x+1,12 SAY 'Код раздела:' GET cDefName PICTURE "@KS30"
 SETCURSOR(1); READ ; SETCURSOR(0)
 If LASTKEY() != K_ESC .AND. RecLock()
   FIELD->N_RAZD := cDefName
   dbUnLock()
 EndIF
 RestScreen(x, 0, x+3, MAXCOL(),sWin)
 SETCOLOR(sColor)

RETURN

