//---------------------------------------------------------------------------

#ifndef gui_editH
#define gui_editH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------

#include  "font.h"

#include  "MyTypes.h"

#include  "ide_main.h"
#include  "gui_caret.h"
#include  "ide_popup.h"


class Tgui_edit_Form : public TForm
{                                                                //[2018.02.14.수]
__published:	// IDE-managed Components
        void __fastcall FormMouseDown(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y);
        void __fastcall FormMouseMove(TObject *Sender, TShiftState Shift,
          int X, int Y);
        void __fastcall FormMouseUp(TObject *Sender, TMouseButton Button,
          TShiftState Shift, int X, int Y);
          
private:	// User declarations
public:		// User declarations

        __fastcall Tgui_edit_Form(TComponent* Owner);

        //[2012.04.29.일][완료!!!]
        __fastcall ~Tgui_edit_Form(void);

        //[서브클래싱]
        //{
            //[2018.02.14.수][완료!!!]
            void __fastcall WndProc(Messages::TMessage &Message);

        //}

        //[VAR]
        //{
            //[환경변수]
            //{
                //[2007.10.02.화][추가!!!]
                struct  IDE_OPTION   *_ide_option;

            //}

            //[실제 그리는 영역]{-----------
            Graphics::TBitmap  *_bmp_;

            //편집기 배경 그림.
            Graphics::TBitmap  *_bmp_back_;
            //}-----------------------------

            //[사용글꼴]{--------------
            struct FONTPACK     _font;
            //}------------------------

            //사용 폰트를 적용한 한 행의 높이.
            int                 _line_height;
            //사용 폰트를 적용한 문자 한개의 넓이.
            int                 _word_width;

            //[편집용버퍼]
            //{
                //기본 크기로 10M 용량으로 설정한다.
                //옵션으로 조정 할수 있어야 하므로 동적생성할수 있도록 한다.
                char               *_editbuf;
                //실제 [편집] 을 위한 [저장소] 는 한개만 있으므로 아예 충분한 크기를 갖도록
                //하여 이 안에서 수정시에도 [저장소] 의 크기를 변경할 필요가 없게 만든다.
                //10M 정도면 충분할 것이다.

            //}

            //[내부 임시 처리 저장소]
            //{
                //[2007.04.09.월][추가!!!]
                //_editbuf[] 상에 [문자/문자열] 을 끼워 넣기 위한 [공간만들기] 를 할때
                //for() 문을 사용하는 것은 문서량이 많은 경우는 처리 속도가 느리다.
                //memmove() 함수를 사용할수 있으면 고속 처리가 가능한데, 한개의 저장소로는 불가능하므로
                //_editbuf[] 와 같은 크기의 [저장소] 를 만들어서 memmove() 함수를 사용하여 밀어낼 문자열부분을
                //이곳에 복사하고 -> 문자열을 끼워 넣은후 -> 다시 북사해서 이어주는 방법을 사용한다.
                //전부 memmove() 함수를 사용하게 되므로 고속으로 처리할수 있다.
                char               *_tempbuf;

            //}

            //[2007.09.28.금][추가!!!]
            //{
                //실제 줄이동막대가 없으므로 가상적으로 위치를 지정하여 운영한다.
                int _scroll_h_position;

            //}

            //[2008.02.03.일][추가!!!]{-----------------------------------------
            //[풍선도움말] 에 출력할 문자열을 가진다.
            //단, 메모리 낭비를 막기 위하여 해당 사용이 설정된 경우만 처리한다.
            bool   _balloonHelpUse; //(기본 : false)

            //동적 생성시 크기를 주어 설정한다.
            char  *_balloonHelpStr;
            //}-----------------------------------------------------------------

        //}

        //[내부 사용 개체]
        //{
            //[간편기능목록]
            //{
                //[2007.03.06.화][추가!!!]
                Tide_popup_Form  *_popup_menu_;

                //[동작함수]
                //{
                    //[간편기능항목] 에서 항목이 선택된 경우 호출된다.
                    //[2007.03.31.토][완료!!!]
                    void __fastcall _EVENT_PopupMenu(void);

                //}
                
            //}

            //[Enter 키 동작 함수]
            //{
                //[2009.04.10.금][추가!!!]{----------
                //[Enter Key] 가 눌린 경우 발생한다.
                //}----------------------------------

                void __fastcall (__closure * _EVENT_KeyEnter)(void);

                //[2012.05.20.일][추가!!!]
                //<키:ESC> 가 눌린 경우 동작.
                void __fastcall (__closure * _EVENT_KeyDown_Esc)(void);


                //[2019.03.02.토][추가]
                //{
                    //[!]{---------------------------------------------------
                    //[찾기:대화상자] 의 [근접단어:정렬] 기능 지원을 위한것.
                    //}------------------------------------------------------

                    //[내용] 의 변경이 있는 경우 발생(문자입/삭제/잘라내기/붙이기 등 전부 포함).
                    void __fastcall (__closure * _EVENT_Change)(void);

                    void __fastcall (__closure * _EVENT_KeyDown_Left)(void);

                    void __fastcall (__closure * _EVENT_KeyDown_Right)(void);

                    void __fastcall (__closure * _EVENT_KeyDown_Up)(void);

                    void __fastcall (__closure * _EVENT_KeyDown_Down)(void);

                    void __fastcall (__closure * _EVENT_KeyDown_Home)(void);

                    void __fastcall (__closure * _EVENT_KeyDown_End)(void);

                //}

            //}

        //}

        //[FUNCTION]
        //{
            //[2008.02.03.일][완료!!!]{--------------------
            void __fastcall _BalloonHelpUse(bool    pUse);
            void __fastcall _BalloonHelpStr(char   *pStr);
            //}--------------------------------------------

            void __fastcall _Shape(void);

            void __fastcall _Draw(void);

            void __fastcall _Width(int  pWidth);

            //[2007.03.26.월][완료!!!]
            void __fastcall _EditBuf_Text(void);

            //[2006.12.17.일][완료!!!]
            void __fastcall _EditBuf_Clear(void);

            void __fastcall _EDIT_Get_TextOrigin(void);
            void __fastcall _EDIT_H_Scroll(void);

        //}

        //[배경색]
        //{
            //[2012.09.23.일][추가!!!]{------------------------------------------
            //[검증식 작성] 기능을 <editor_edit> 에 추가하는 중 필요하여 만든다.
            //}------------------------------------------------------------------

            //[VAR]
            //{
                int  _backColor;

            //}

            //[2012.09.23.일][완료!!!]
            void __fastcall _BackColor(int  pColor);

        //}

        //[편집관련]
        //{
            //[VAR]
            //{
                //[기준값]
                //{
                    //[한글/영문] 의 각각의 대표 문자의 [폭] 값을 가진다.
                    //현재 [편집기] 에는 고정폭 글꼴만 사용되므로 [한글/영문] 각각 한개의
                    //[문자폭] 은 다른 처리를 위하여 가지고 있어야 한다.
                    //이 값은 [글꼴] 을 생성할때 한번만 구해놓으면 된다.
                    int  _font_kor_width;
                    int  _font_eng_width;
                //}

                //[가상원점]
                //{
                    //실제 문서가 출력되는 문서 영역의 원점이 된다.
                    //[입력지정자] 위치, [행/열] 표시 등도 전부 이 원점 좌표를 기준으로 한다.
                    int  _text_org_x;
                    int  _text_org_y;
                //}

                //[관리]
                //{
                    //[문서] 의 총 행수를 기록한다.
                    //산출하는데 시간이 많이 거리므로 항상 추척 관리 해 놓아야 한다.
                    //행이 바뀌는 [문서수정] 의 경우(Enter/Del/Back 키 와 잘라내기, 붙이기) 는
                    //즉시 행수를 계속 추척하여 정확한 값을 기록해 놓아야 한다.
                    //또한, 문서를 여는 경우는 기본적으로 값을 기록해 놓는다.
                    //단, [행 수] 는 1 부터 의미가 있다. ([행 번호] 는 0 부터 의미가 있으므로 혼동하지 않아야 한다.)
                    //완전 공백이라도 [입력지정자] 가 위치해야 하므로 최소한 한개의 행은 있어야한다.
                    int  _linecount; //(BASE : 1)

                    //현재 행의 _editbuf[] 상의 시작 index(행의 첫 문자 위치) 를 관리한다.
                    //어떤 상황에서도 가장 먼저 수정되 있어야 하고 항상 정확한 값을 가지고 있어야 한다.
                    int  _linestartindex; //(BASE : 0)

                    //_linestartindex 와는 달리 항상 추적할 필요는 없고 필요할때 사용된다.
                    //현재 행의 마지막 문자 위치 + 1 의 위치를 갖는다.
                    //일반적인 경우는 행의 끝의 CRLF 의 CR(0x0d) 의 위치가 되지만 마지막 행이
                    //CRLF 로 끝나지 않은 경우도 있으므로 일반적으로 마지막 문자 위치 + 1 의 위치로
                    //정의 하면 무난하다.
                    int  _lineendindex; //(BASE : 0)

                    //현재 _editbuf[] 에 있는 문서의 byte 단위 크기.(문자열의 경우 '\0' 까지 포함한 크기다.)
                    //FILE_Open_inBUF() 함수로 파일을 여는 경우는 문자열의 경우 '\0' 까지 크기에 포함된다.
                    int  _filesize;

                    //[보이는 가장 윗행]
                    //{
                        //일반적으로 [스크롤] 되는 경우 윗행이 바뀌게 되므로 이때 수정한다.

                        //[편집기] 창에서 보이는 가장 윗행의 [행 번호] 를 관리한다.
                        //[행 번호] 는 0 부터 유효하다.
                        int  _linetop_linenumber; //(BASE : 0)

                        //[편집기] 창에서 보이는 가장 윗행의 시작 index 를 관리한다.
                        int  _linetop_startindex; //(BASE : 0)
                    //}

                    //[중요!!!]
                    //{
                        //------------------------------------------------------------------------
                        //_editbuf[] 상의 현재 [입력지정자] 가 위치한 문자의 index 를 갖는다.
                        //가장 기본이 되는 값이며, 다른 모든 연산의 기준이 되므로 언제나 추적하여
                        //정확한 값을 가지고 있어야 한다.
                        int  _caretindex; //(BASE : 0)

                        //_caretindex 위치의 실제 표시상의 행 처음부터의 [폭] 을 가진다.
                        int  _caretindexwidth; //(BASE : 0)
                        //------------------------------------------------------------------------
                    //}

                    //[행/열]
                    //{
                        //-----------------------------------------------------------------------------
                        //[입력지정자] 의 상/하 이동시에는 이 [열] 정보를 사용해서 위치를 찾아야 한다.
                        //이 정보는 editor_info_Form 의 해당 위치에 즉시 표시 될수 있어야 한다.
                        int  _row;
                        int  _col;
                        //-----------------------------------------------------------------------------
                    //}
                    
                //}

                //[입력지정자]
                //{
                    //-------------------------------------------------------
                    //개체를 갖는다.
                    Tgui_caret_Form  *_caret;

                    //표시 위치.
                    //(_text_x, _text_y) 위치를 기준으로 한다.
                    //이 값은 offset 좌표 이므로 절대로 "음수" 가 될수 없다.
                    int  _caret_x; //(BASE : 0)
                    int  _caret_y; //(BASE : 0)
                    //-------------------------------------------------------
                //}

                //문자한개를 저장한다.(한글/영문 일수 있으므로 2byte 값을 가지게 한다.)
                short  _moonja;
                bool   _ime_TkorFeng; //(BASE : false)

                //[2008.02.13.수][추가!!!]{-------------------------------------------------------------
                //한글 조함중 영문등이 입력되면 한글 조합이 완성되는데 이때 입력한 기호등도
                //출력해 주어야 하는데 이때 한글 조합을 깬 문자를 가진다.
                //예) 한글 조함중 '2' 를 입력하여 조합이 깨졌다면 '2' 문자가 들어 있어야 한다.
                //이를 위하여 WM_IME_COMPOSITION 처리부에서 ImmGetCompositionString() 함수를
                //사용하여 "한2" 으로 문자열을 읽어서 처리할수 있다.
                //중요힌것은 '2' 문자를 얻는 것이 중요한다. '한' 은 WParam 으로 쉽게 얻을수 있으므로...

                HIMC   _imeHimc;         //IME 핸들.
                char   _imeBuffer[1024]; //ime 버퍼에 저장된 문자열을 읽을때 사용한다.
                int    _imeBufcount;
                //}-------------------------------------------------------------------------------------

                //_EditBuf_Text() 함수내부를 처리할지를 결정한다.
                //이는 [스크롤] 시에 중복되어 깜박이는 것을 방지하기 위한 것이다.
                bool  _editbuf_text_on;  //(BASE : true)
                bool  _edit_caretpos_on; //(BASE : true)
                //[2007.03.08.목][추가!!!]
                bool  _edit_paste_ing;   //(BASE : true)
                //[2007.03.09.금][추가!!!]
                bool  _editbuf_text_no;  //(BASE : false)

                //[블록지정][2007.01.22.월]
                //{
                    //--------------------------------------------------------------------------
                    //[문서] 가 블록으로 지정되는 경우 관련 정보를 저장한다.
                    //이 정보는 [문서] 마다 전부 독립적인 것이므로 [문서] 마다 별도로 관리한다.
                    //각각 -1 로 초기화 하는데 이것은 현재 [선택영역] 이 없다는 것을 말한다.
                    //둘중 하나라도 -1 인 경우는 [선택영역이 없는 것으로 본다.]

                    //[선택영역] 을 시작하는 문자의 시작위치(시작 [입력지정자] 위치).
                    struct CARETINFO  _select_start;

                    //[선택영역] 이 끝나는 문자 다음 문자의 위치(끝 [입력지정자] 위치).
                    //끝문자의 시작 위치가 아니다.
                    //이는 [선택영역] 문자열의 길이를 쉽게 계산하기 위한 것이다.
                    //한글의 경우 2 byte 문자이므로 첫 문자인 경우 계산이 복잡해지기 때문이다.
                    //즉, 이 위치의 문자부터는 일반출력을 적용해 주어야  한다.
                    struct CARETINFO  _select_end;

                    //[주의!!!][2007.02.14.수][추가!!!]
                    //이 값은 [선택영역] 을 설정해 가는 방향에 따라서 꼭 "start < end" 의
                    //관계가 성립되지는 않으므로 반드시 _SELECT_Get_StartEndIndex() 함수로
                    //크기 순서대로 정리한 값을 사용해야 한다.
                    //--------------------------------------------------------------------------

                    //[부가정보]
                    //{
                        //[선택영역] 을 형성하는 과정에서 사용된다.(만들때는 위의 두개 정보만 있으면 된다.)
                        //[마우스] 로 집어끌기를 하여 [선택영역] 을 형성할때, [shift + 키] 를 사용하여
                        //[선택영역] 을 형성해 갈때 현재 이미 선택영역이 형성상태임을 알려준다.
                        //true  : 현재 [선택영역] 형성이 시작된 상태다.
                        //false : [선택영역] 이 해제된 상태.
                        bool  _select_ing;
                    //}
                //}

                //[2007.02.09.금][추가!!!]
                //[마우스] 가 [눌린상태(true)] 라는 것을 알린다.
                bool  _mouse_down; //(BASE : false)

                //[2007.02.10.토][추가!!!]
                //<shift-key> 가 눌린 상태인 경우는 true.
                bool  _shift_down; //(BASE : false)

                //[2007.02.11.일][추가!!!]
                //현재 [줄이동] 중인 경우는 true.
                bool  _scroll_ing; //(BASE : false)
            //}

            //[함수]
            //{
                //[2007.01.18.목][완료!!!]
                void __fastcall _EDIT_Init(void);


                //[2010.06.28.월][완료!!!]
                void __fastcall _EDIT_TextOut(char  pText[]);



                //[2006.12.19.화][완료!!!]
                bool __fastcall _EDIT_IS_ImeHangul(void);
                void __fastcall _EDIT_Change_ImeMode(void);

                //[2007.04.08.일][완료!!!]
                void __fastcall _EDIT_CaretPos(int  pX,
                                               int  pY);
                //[2006.12.27.수][완료!!!]
                void __fastcall _EDIT_Get_Kor_Eng_Moonja_Width(void);

                //[2018.02.24.토][완료!!!]
                void __fastcall _CARETINDEX_CaretIndexWidth(int   pLINEstartINDEX,
                                                            int   pCARETINDEX,
                                                            int  *rCARETINDEXwidth,
                                                            int  *rMOONJAcount);
                //[2006.12.27.수][완료!!!]
                void __fastcall _CARETINDEXWIDTH_CaretIndex(int   pLINEstartINDEX,
                                                            int   pLINEendINDEX,
                                                            int  *prCARETINDEXwidth,
                                                            int  *rCARETINDEX,
                                                            int  *rMOONJAcount);
                //[2006.12.27.수][완료!!!]
                void __fastcall _CARETINDEX_MoveLeft(int   pLINEstartINDEX,
                                                     int  *prCARETINDEX);
                //[2006.12.27.수][완료!!!]
                void __fastcall _CARETINDEX_MoveRight(int   pLINEendINDEX,
                                                      int  *prCARETINDEX);

                //[2007.03.01.목][완료!!!]
                void __fastcall _MOUSEDOWN_Get_LineStartIndex(int   pLINEnumber,
                                                              int  *pLINEstartindex);

                //[2007.03.19.월][완료!!!]
                bool __fastcall _CARETPOS_MouseDown(int  pMOUSEdownX,
                                                    int  pMOUSEdownY);

                //[2007.03.17.토][완료!!!]
                void __fastcall _ROOT_TEXTINFO_Init(void);

                //[2007.03.14.수][완료!!!]
                void __fastcall _KEY_Left(bool  pETCcontrol);
                //[2007.03.14.수][완료!!!]
                void __fastcall _KEY_Right(bool  pETCcontrol,
                                           bool  pSELECTtrue);

                //[2007.03.14.수][완료!!!]
                void __fastcall _KEY_Home(bool  pETCcontrol);
                //[2007.03.14.수][완료!!!]
                void __fastcall _KEY_End(bool  pETCcontrol);

                //[2007.03.26.월][완료!!!]
                void __fastcall _KEY_Delete(void);
                //[2007.03.13.월][완료!!!]
                void __fastcall _KEY_Backspace(void);

                //[2007.01.18.목][완료!!!]
                bool __fastcall _EDITBUF_MOONJA_Delete(int    pDELETEindex,
                                                       bool  *rIScrlf);
                //[2007.02.14.수][완료!!!]
                bool __fastcall _SELECT_Get_StartEndIndex(struct CARETINFO  *rSELECTstart,
                                                          struct CARETINFO  *rSELECTend);
                //[2007.02.14.수][완료!!!]
                bool __fastcall _SELECT_Delete(struct CARETINFO  *rSELECTstart,
                                               int               *rCRLFcount);
                //[2007.04.09.월][완료!!!]
                void __fastcall _EDITBUF_MOONJA_Insert(int    pINSERTindex,
                                                       short  pCODE);
                //[2018.02.20.화][완료!!!]
                void __fastcall _CARET_MOONJA_Insert(short  pCODE);

                //[2007.03.19.월][완료!!!]
                void __fastcall _SELECTSCROLL_Left(int  pMOUSEx);
                //[2007.03.19.월][완료!!!]
                void __fastcall _SELECTSCROLL_Right(int  pMOUSEx);

                //[2007.03.07.수][완료!!!]
                void __fastcall _EDIT_SelectDelete(void);

                //[2018.02.24.토][완료!!!]
                void __fastcall _EDIT_Paste(char *pPASTEstr);

                //[2007.03.21.수][완료!!!]
                void __fastcall _EDIT_SelectAll(void);
            //}

            //[문자열처리]
            //{
                //한줄만 관리 하면 되므로 1024 개 문자만 관리하면 충분하다.
                #define  d_WORDCONFIG_max   1024
                struct WORDCONFIG _wordconfig[d_WORDCONFIG_max];
                int               _wordconfig_count;

                //[2007.01.31.수][완료!!!]
                void __fastcall _WORD_LineGet(char  *pSTR,
                                              int    pINDEX,
                                              char   rWORD[],
                                              int   *rWORDindex,
                                              int   *rWORDlength);

                //[2007.02.03.토][완료!!!]
                void __fastcall _MOONJACONFIG_LineGet(int  pLINEstartindex);

                //[2007.04.15.일][완료!!!]
                bool __fastcall _EDITBUF_LINE_Out(int   pX,
                                                  int   pY,
                                                  int   pLINEstartindex,
                                                  int  *rLINEendindex);

                //[2007.02.02.금][완료!!!]
                bool __fastcall _EDITBUF_STRING_Out(int  pX,
                                                    int  pY,
                                                    int  pLINEstartindex);

                //[2007.03.11.일][완료!!!]
                bool __fastcall _CARET_ViewAlways(void);
            //}

            //[클립보드관련]
            //{
                //[2007.03.06.화][완료!!!]
                bool __fastcall _CLIPBOARD_IsText(void);
                //[2012.04.29.일][완료!!!]
                void __fastcall _CLIPBOARD_Copy(void);
                //[2007.03.22.목][완료!!!]
                void __fastcall _CLIPBOARD_Cut(void);
                //[2007.03.07.수][완료!!!]
                void __fastcall _CLIPBOARD_Paste(void);
            //}
        //}

};

//---------------------------------------------------------------------------
extern PACKAGE Tgui_edit_Form *gui_edit_Form;
//---------------------------------------------------------------------------

#endif
