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

#include <vcl.h>
#pragma hdrstop

#include "editor_linebox.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
Teditor_linebox_Form *editor_linebox_Form;
//---------------------------------------------------------------------------


#include "ide_main.h"
#include "ide_editor.h"
#include "editor_edit.h"
#include "editor_top.h"
#include "gui.h"


__fastcall Teditor_linebox_Form::Teditor_linebox_Form(TComponent* Owner)
        : TForm(Owner)
{
  //[2006.12.06.수][생성!!!]{-------------
  //테두리마나 있는 사각형을 만든다.
  //폼을 오려내기하여 선만 보이게 만든다.
  //}-------------------------------------

  //[환경변수]
  //{
      //[2007.10.02.화][추가!!!]
      IDE_Get_Option(&_ide_option);

  //}

  //[초기화]
  //{
      this->Color  = IDE_COLOR_linebox;
      this->Width  = 30;
      this->Height = 14 + 16;
  //}

  //[bmp]
  //{
      //실제 그림 영역을 생성한다.
      _bmp_ = new Graphics::TBitmap;

      //그림 영역 크기 설정.
      //문자열을 출력하는 영역크기만큼만 설정한다.
      _bmp_->Width       = Screen->Width;
      _bmp_->Height      = this->Height;

      //24bit bitmap 으로 지정한다.
      _bmp_->PixelFormat = pf24bit;

      //전체 색은 한번만 칠해주면된다.
      //수정되는 부분은 한정되 있으므로.
      _bmp_->Canvas->Brush->Color = IDE_COLOR_linebox;
      _bmp_->Canvas->FillRect(_bmp_->Canvas->ClipRect);
  //}

  //[글꼴 설정]
  //{
      //[기본 끌꼴 등록]{------------------------------------------------
      //모든 프로그램에서 기본적으로 사용하는 [system 글꼴] 을 등록한다.
      FONTPACK_SetDefault(&_font);
      //}----------------------------------------------------------------

      _font.margin_size   = 0;

      _font.offset_left   = 0;
      _font.offset_right  = 0;
      _font.offset_top    = 0;
      _font.offset_bottom = 0;
      
      //[2010.01.26.화][추가!!!]{---
      _font.en_offset_left  = 0;
      _font.en_offset_right = 0;
      //}---------------------------
  //}

  _SetPosition(0);

  return;

}

__fastcall Teditor_linebox_Form::~Teditor_linebox_Form(void)
{
  //[소멸]

  return;

  delete _bmp_;

  return;

}

//[서브클래싱]------------------------------------------------------------------

void __fastcall Teditor_linebox_Form::WndProc(Messages::TMessage  &Message)
{
  //[2006.12.12.화][생성!!!]{-----------------------------------------------------
  //TForm 의 경우는 바탕을 칠하고 OnPaint() 를 발생하게 되므로 실제 _Draw() 를
  //OnPaint() 에서 사용하는 경우는 크기가 변경되는 경우 바로 칠해지지 않아서
  //하얀색 바탕이 그대로 나오게 되어 보기 좋지 않게 된다.
  //따라서 TForm 자체의 바탕을 그리는 WM_ERASEBKGND 에서 바로 _Draw() 를 사용하여
  //그리고 OnPaint() 는 처리하지 않는다.
  //C++Builder 와 같이 완벽하게 처리되는 깜박임이 전혀 없는 화면을 만들수 있다.
  //}-----------------------------------------------------------------------------

  if(Message.Msg == WM_ERASEBKGND)
  {
    _Draw();

    //바로 죵료하지 않으면 WM_ERASEBKGND 메세지가 다음 TForm::WndProc(Message); 에서
    //다시 처리 되어 TForm->Color 로 칠해지게 되어 _Draw() 로 그린 것이 다 지워지므로
    //바로 종료한다.
    return;

  }

  //[기본처리]
  //{
      //기본 메세지는 반드시 처리 되어야 한다.
      TForm::WndProc(Message);
  //}

  return;

}

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

void __fastcall Teditor_linebox_Form::_Top(int  pTOP)
{
  //[2006.12.06.수][생성!!!]

  this->Top = pTOP;

  return;

}

void __fastcall Teditor_linebox_Form::_Left(int  pLEFT)
{
  //[2006.12.06.수][생성!!!]

  this->Left = pLEFT;

  return;

}

void __fastcall Teditor_linebox_Form::_Width(int  pWIDTH)
{
  //[2006.12.06.수][생성!!!]{--------------
  //폭이 바뀐경우는 다시 그려 주어야 한다.
  //}--------------------------------------

  this->Width = pWIDTH;

  //반드시 _FormCut() 보다 먼저 그려주어야 한다.
  _BottomPanel();

  _FormCut();

  return;

}

void __fastcall Teditor_linebox_Form::_Size(int  pWIDTH,
                                            int  pHEIGHT)
{
  //[2006.12.06.수][생성!!]

  this->Width  = pWIDTH;
  this->Height = pHEIGHT;

  //반드시 _FormCut() 보다 먼저 그려주어야 한다.
  _BottomPanel();

  _FormCut();

  return;

}

void __fastcall Teditor_linebox_Form::_Show(void)
{
  //[2006.12.06.수][생성!!]

  //[크기 조정]
  //{
      //[2009.05.05.화][추가!!!]{--------------------------------
      //보여질때 정확한 크기가 아니라면 다시 크기를 조정해 준다.
      //}--------------------------------------------------------

      if(this->Width != (editor_edit_Form->Width - d_gutter_width - 13))
      {
        //정확한 크기로 조정한다.
        this->Width = (editor_edit_Form->Width - d_gutter_width - 13);

        //반드시 _FormCut() 보다 먼저 그려주어야 한다.
        _BottomPanel();
        _FormCut();

      }

  //}

  this->Visible = true;

  return;

}

void __fastcall Teditor_linebox_Form::_Hide(void)
{
  //[2006.12.06.수][생성!!]

  this->Visible = false;

  return;

}

void __fastcall Teditor_linebox_Form::_FormCut(void)
{
  //[2006.12.06.수][생성!!!]{--
  //폼에 구멍을 낸다.
  //}--------------------------

  //[VAR]
  //{
      //대상 폼.
      HRGN    rgn_main;

      //구멍낼 영역.
      HRGN    rgn_cut_rect_ti,
              rgn_cut_rect_btl,
              rgn_cut_rect_btlt,
              rgn_cut_rect_bbl,
              rgn_cut_rect_bblt,
              rgn_cut_rect_br;

      //삼각형 모양을 잘라내기 위한 정보.
      POINT   point_l[3];
      POINT   point_r[3];
  //}

  //[Form 초기화]
  //{
      //포인터 초기화.
      rgn_main = 0;

      //Form 의 영역 정보를 얻는다.
      GetWindowRgn(this->Handle, rgn_main);

      //일단 현재 Form 영역을 지운다.
      DeleteObject(rgn_main);
  //}

  //[영역 생성]
  //{
      //새로운 영역을 생성한다.
      rgn_main = CreateRectRgn(0, 0, this->Width, this->Height);

      //[구멍 뚫을 영역 지정]
      //{
          rgn_cut_rect_ti = CreateRectRgn(1,
                                          1,
                                          this->Width - 1,
                                          this->Height - 1 - 16);

          rgn_cut_rect_br = CreateRectRgn(d_LINEBOX_textwidth,
                                          14 + 8,
                                          this->Width,
                                          this->Height);
      //}

      //[영역 합성]
      //{
          CombineRgn(rgn_main, rgn_main, rgn_cut_rect_ti, RGN_DIFF);
          CombineRgn(rgn_main, rgn_main, rgn_cut_rect_br, RGN_DIFF);

          SetWindowRgn(this->Handle, rgn_main, TRUE);
      //}
  //}

  //[구멍 뚫기]
  //{
      //지정 영역에 구멍을 뚫는다.
      DeleteObject(rgn_cut_rect_ti);
      DeleteObject(rgn_cut_rect_br);
  //}

  return;

}

void __fastcall Teditor_linebox_Form::_SetPosition(int  pLINEnumber)
{
  //[2006.12.07.목][생성!!!]{-------------------------------------
  //[실행지정상자] 를 지정 행에 위치시킨다.
  //행의 높이등의 정보는 editor_edit_Form 의 정보를 참고한다.
  //단, 이 Form 이 보이는 경우에만 처리되어야 낭비를 막을수 있다.
  //}-------------------------------------------------------------

  //[VAR]
  //{
      AnsiString  str;
      int         w, h;
      TRect       rect;

      int         color;
  //}

  //[예외]
  //{
      //폼이 보이지 않는 경우는 처리하지 않는다.
      if(this->Visible != true) return;
  //}

  //[테마색처리]
  //{
      //테마색 구하기.
      BMP_Get_Bright_Color(IDE_COLOR_linebox, IDE_BRIGHT_linebox, &color);
  //}

  //[문자열 영역 지우기]
  //{
      //문자열이 표시되는 영역을 지운다.
      rect.Left   = 0;
      rect.Top    = 13;
      rect.Right  = d_LINEBOX_textwidth;
      rect.Bottom = 14 + 16;

      _bmp_->Canvas->Brush->Color = color;
      _bmp_->Canvas->FillRect(rect);
  //}

  //[행정보 표현]
  //{
      //행문자열 합성.
      str = "행:" + IntToStr(pLINEnumber);

      //문자열 출력.(음각으로 출력한다.)
      FONT_Out_StyleString2(_bmp_, &_font, 6, 14 + 2, IDE_COLOR_3, color, true,
                            d_FONTSTYLE_default,
                            str.c_str(),
                            d_FONT_underline_no, true, 1, IDE_COLOR_1,
                            &w, &h);
  //}

  //[테두리 만들기]
  //{
      _bmp_->Canvas->Pen->Color   = IDE_COLOR_linebox;
      _bmp_->Canvas->Pen->Width   = 1;
      _bmp_->Canvas->Brush->Style = bsClear;
      _bmp_->Canvas->Rectangle(rect);
  //}

  //[반영]
  //{
      _Draw();
  //}

  //[위치 수정]
  //{
      //지정행에 위치하도록 수정한다.
      this->Top = (-1) * ide_editor_Form->_scroll_v_Form->_position * editor_edit_Form->_line_height +
                  d_editorTopHeight +
                  (pLINEnumber * editor_edit_Form->_line_height);
  //}

  return;

}

void __fastcall Teditor_linebox_Form::_BottomPanel(void)
{
  //[2007.04.17.화][생성!!!]{-------------------------------------------
  //오른쪽 하단부의 영역을 규칙무늬로 채워준다.
  //반드시 _FormCut() 보다 먼저 그려주어야 한다.
  //크기 조정시 _FormCut() 보다 나중에 사용하면 제대로 그려지지 않는다.
  //}-------------------------------------------------------------------

  //[VAR]
  //{
      TRect  rect;
      int    x, y;
      int    i;

      int    color;
  //}

  //[테마색처리]
  //{
      //테마색 구하기.
      BMP_Get_Bright_Color(IDE_COLOR_linebox, IDE_BRIGHT_linebox, &color);
  //}

  //[바탕 지우기]
  //{
      rect = _bmp_->Canvas->ClipRect;

      rect.Left   = d_LINEBOX_textwidth - 1;
      rect.Top    = 14 - 1;
      rect.Bottom = 14 + 8;
      rect.right  = this->Width;

      _bmp_->Canvas->Pen->Color   = color;
      _bmp_->Canvas->Brush->Color = color;
      _bmp_->Canvas->FillRect(rect);
  //}

  //[규칙무늬 만들기]
  //{
      for(x = rect.Left, i = 1; x < rect.Right ; x++)
      {
        for(y = rect.Top; y < rect.Bottom; y++, i++)
        {
          if(i%2 == 0)
          {
            //지정색.
            BMP_Dot(_bmp_, x, y, IDE_COLOR_linebox);

          }
          else
          {
            //테마색.
            BMP_Dot(_bmp_, x, y, color);

          }
        }
      }
  //}

  //[테두리 만들기]
  //{
      _bmp_->Canvas->Pen->Color   = IDE_COLOR_linebox;
      _bmp_->Canvas->Pen->Width   = 1;
      _bmp_->Canvas->Brush->Style = bsClear;
      _bmp_->Canvas->Rectangle(rect);
  //}

  return;

}

void __fastcall Teditor_linebox_Form::_Draw(void)
{
  //[2007.04.16.월][생성!!!]

  BitBlt(this->Canvas->Handle, 0, 0,
         this->Width, this->Height,
         _bmp_->Canvas->Handle, 0, 0, SRCCOPY);

  return;

}

void __fastcall Teditor_linebox_Form::_RePaint(int   pLineNumber)
{
  //[2007.12.03.월][생성!!!{---------------------------------
  //색을 바꾼경우 바로 반영하기 위하여 전부다 다시 그려준다.
  //색만 바꾸면 되므로 폼을 다시 오려내지 않아도 된다.
  //}--------------------------------------------------------

  //[전체 색 칠하기]
  //{
      //수정되는 부분은 한정되 있으므로.
      _bmp_->Canvas->Brush->Color = IDE_COLOR_linebox;
      _bmp_->Canvas->FillRect(_bmp_->Canvas->ClipRect);

  //}

  //행번호를 그려준다.
  _SetPosition(pLineNumber);

  //오른쪽 아래 무늬를 만든다.
  _BottomPanel();

  //다시 반영한다.
  _Draw();

  return;

}

//[EVENT]-----------------------------------------------------------------------

void __fastcall Teditor_linebox_Form::FormShow(TObject *Sender)
{
  //[2007.04.16.월][생성!!!]{------------------------------------
  //폼을 오리는 경우 폼이 처음 보일때 한번은 호출해 주어야 한다.
  //}------------------------------------------------------------

  //반드시 _FormCut() 보다 먼저 그려주어야 한다.
  _BottomPanel();

  _FormCut();

  return;

}




