// not UNIX
// MainFrm.cpp : implementation of the CMainFrame class
//

#include "stdafx.h"
#include "Strawberry.h"

#include "MainFrm.h"
#include "StrawberryDoc.h"
#include "StrawberryView.h"
#include "ChildFrm.h"
#include "Splash.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CMainFrame

IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
  ON_WM_CREATE()
  ON_WM_CLOSE()
  ON_WM_TIMER()
  // Global help commands
  ON_COMMAND(ID_HELP_FINDER, CMDIFrameWnd::OnHelpFinder)
  //ON_COMMAND(ID_HELP, CMDIFrameWnd::OnHelp)
  ON_COMMAND(ID_CONTEXT_HELP, CMDIFrameWnd::OnContextHelp)
  ON_COMMAND(ID_DEFAULT_HELP, CMDIFrameWnd::OnHelpFinder)
  //ON_COMMAND(ID_HELP_INDEX, CMDIFrameWnd::OnHelpIndex)
  ON_MESSAGE( WM_USER, ReBuild)
  ON_MESSAGE( WM_USER+1, OnEnd)
  ON_MESSAGE( WM_USER+2, OpenOutput)
  ON_MESSAGE( WM_USER+3, NewIndLine)
  
  ON_UPDATE_COMMAND_UI(ID_INDICATOR_LINE, OnUpdateIndicatorLine)
  ON_COMMAND(ID_HELP_ADDFILE, OnHelpAddFile)
  ON_COMMAND(ID_HELP, OnHelpMain)
  ON_WM_HELPINFO()
  ON_COMMAND(ID_HELP_ONLINE, OnHelpOnline)
  ON_COMMAND(ID_HELP_WWW, OnHelpWww)
  ON_COMMAND(ID_TOOLS_SYNTAXCOLORING, OnToolsSyntaxColoring)
  ON_COMMAND(ID_TOOLS_HIDESYNTAXCOLORING, OnToolsHideSyntaxColoring)
END_MESSAGE_MAP()

static UINT indicators[] =
{
    ID_SEPARATOR,           // status line indicator
    ID_INDICATOR_LINE,
    ID_INDICATOR_CAPS,
    ID_INDICATOR_NUM,
};


// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
  m_paneString="Ln 1, Col 1";    
}

CMainFrame::~CMainFrame()
{
}


int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    
    if (!m_wndToolBar.CreateEx(this, (Environment&0x8000)?TBSTYLE_TRANSPARENT:TBSTYLE_FLAT,
      WS_CHILD | WS_VISIBLE | CBRS_TOP
        | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
        !m_wndToolBar.LoadToolBar((Environment&1024)?IDR_MAINFRAME_BIG:IDR_MAINFRAME))
    {
        TRACE0("Failed to create toolbar\n");
        return -1;      // fail to create
    }

    if (!m_wndStatusBar.Create(this) ||
        !m_wndStatusBar.SetIndicators(indicators,
          sizeof(indicators)/sizeof(UINT)))
    {
        TRACE0("Failed to create status bar\n");
        return -1;      // fail to create
    }
    // TODO: Delete these three lines if you don't want the toolbar to be dockable
    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
    EnableDocking(CBRS_ALIGN_ANY);
    DockControlBar(&m_wndToolBar);

  CClientDC dc(this);
  m_wndStatusBar.SetPaneInfo(1, ID_INDICATOR_LINE, SBPS_NORMAL,
     dc.GetTextExtent(m_paneString).cx);

    // CG: The following line was added by the Splash Screen component.
    CSplashWnd::ShowSplashScreen(this);

    return 0;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    if( !CMDIFrameWnd::PreCreateWindow(cs) )
        return FALSE;
    // TODO: Modify the Window class or styles here by modifying
    //  the CREATESTRUCT cs

    cs.style = WS_OVERLAPPED | WS_CAPTION | FWS_ADDTOTITLE
         | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_MAXIMIZE | WS_SYSMENU;

    return TRUE;
}

void CMainFrame::OnTimer(UINT nIDEvent) 
{
  if (pActiveFile && !(status_fl&18)) // not running and not painting
  {
    if (pActiveFile->m_CharSet&0x100)
    {
      pActiveFile->m_CharSet&=0xfffffcff;
      pActiveFile->m_CharSet|=0x200;
    }
    else if ((pActiveFile->m_CharSet&0x380)==0x280 && pActiveFile->m_Star!=0 && pActiveFile->m_Star<5)
    {
      int i=pActiveFile->m_Star; // we don't need to switch off the OnChange but ...
      pActiveFile->m_Star=0;
      SyntaxColoring(59); // 59 is the read Flag
      pActiveFile->m_Star=i;
    }
  }
  CMDIFrameWnd::OnTimer(nIDEvent);
}

// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
    CMDIFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
    CMDIFrameWnd::Dump(dc);
}

#endif //_DEBUG


// CMainFrame message handlers

LONG CMainFrame::ReBuild( UINT wParam, LONG lParam)
{
  CString path;
  CStrawberryDoc *pDoc=(CStrawberryDoc*)((CMDIChildWnd*)lParam)->GetActiveDocument();
  path=pDoc->GetPathName();
  WINDOWPLACEMENT wp;
  ((CMDIChildWnd*)lParam)->GetWindowPlacement(&wp);
  ((CMDIChildWnd*)lParam)->MDIDestroy();
  theApp.OpenDocumentFile(path);
  MDIGetActive()->SetWindowPlacement(&wp);
  return 1;
}

LONG CMainFrame::OpenOutput( UINT wParam, LONG lParam)
{
  FileType=5;
  CStrawberryDoc* pOutputDoc=(CStrawberryDoc*)pDocTemplate2->OpenDocumentFile(NULL);
  pOutputDoc->SetTitle(_T("Output"));
  pOutput=&(pOutputDoc->GetView()->GetRichEditCtrl());
  pDocTemplate2->MyDec();
  return 1;
}

void CMainFrame::OnHelpMain() 
{
  ShellExecute(NULL, NULL, ProgramPath+_T("Strawberry.chm"), NULL, NULL, SW_SHOWNORMAL);
}
BOOL CMainFrame::OnHelpInfo(HELPINFO* /*pHelpInfo*/)
{
  return 1;
}
void CMainFrame::OnHelpOnline() 
{
  ShellExecute(NULL, NULL, ProgramPath+_T("online_help.html"), NULL, NULL, SW_SHOWNORMAL);
}
void CMainFrame::OnHelpWww() 
{
  ShellExecute(NULL, NULL, ProgramPath+_T("dobrev_com.html"), NULL, NULL, SW_SHOWNORMAL);
}

void CMainFrame::OnHelpAddFile() 
{
  if (!pActiveFile)
    return;
  FileType=6;
  if (pActiveFile->m_pInfo->m_AddFile=="Standard.add" || pActiveFile->m_pInfo->m_AddFile=="")
  {
    theApp.OpenDocumentFile(ProgramPath+_T("Standard.add"));
    ((CStrawberryView*)MDIGetActive()->GetActiveView())
         ->GetRichEditCtrl().SetOptions(ECOOP_OR, ECO_READONLY);
  }
  else
    theApp.OpenDocumentFile(pActiveFile->m_pInfo->m_AddFile);
}

void CMainFrame::OnClose() 
{
    DefaultProject.m_Settings &=M1^0x7f800000;
    Environment &=M1^0x7f800000;

    theApp.WriteProfileInt( _T("Default Project\\Font"), _T("lfHeight"), DefaultProject.m_lf.lfHeight);
    theApp.WriteProfileInt( _T("Default Project\\Font"), _T("lfWidth"), DefaultProject.m_lf.lfWidth);
    theApp.WriteProfileInt( _T("Default Project\\Font"), _T("lfEscapement"), DefaultProject.m_lf.lfEscapement);
    theApp.WriteProfileInt( _T("Default Project\\Font"), _T("lfOrientation"), DefaultProject.m_lf.lfOrientation);
    theApp.WriteProfileInt( _T("Default Project\\Font"), _T("lfWeight"), DefaultProject.m_lf.lfWeight);
    theApp.WriteProfileString( _T("Default Project\\Font"), _T("lfFaceName"), DefaultProject.m_lf.lfFaceName);
    if(DefaultProject.m_lf.lfItalic)
      DefaultProject.m_Settings|=0x40000000;
    if(DefaultProject.m_lf.lfUnderline)
      DefaultProject.m_Settings|=0x20000000;
    if(DefaultProject.m_lf.lfStrikeOut)
      DefaultProject.m_Settings|=0x10000000;
    if(DefaultProject.m_lf.lfCharSet)
      DefaultProject.m_Settings|=0x8000000;
    if(DefaultProject.m_lf.lfOutPrecision)
      DefaultProject.m_Settings|=0x4000000;
    if(DefaultProject.m_lf.lfClipPrecision)
      DefaultProject.m_Settings|=0x2000000;
    if(DefaultProject.m_lf.lfQuality)
      DefaultProject.m_Settings|=0x1000000;
    if(DefaultProject.m_lf.lfPitchAndFamily)
      DefaultProject.m_Settings|=0x800000;
    {
    LOGFONT lf;
    InfoFont.GetLogFont(&lf);
    theApp.WriteProfileInt( _T("InfoFont"), _T("lfHeight"), lf.lfHeight);
    theApp.WriteProfileInt( _T("InfoFont"), _T("lfWidth"), lf.lfWidth);
    theApp.WriteProfileInt( _T("InfoFont"), _T("lfEscapement"), lf.lfEscapement);
    theApp.WriteProfileInt( _T("InfoFont"), _T("lfOrientation"), lf.lfOrientation);
    theApp.WriteProfileInt( _T("InfoFont"), _T("lfWeight"), lf.lfWeight);
    theApp.WriteProfileString( _T("InfoFont"), _T("lfFaceName"), lf.lfFaceName);
    if(lf.lfItalic)
      Environment|=0x40000000;
    if(lf.lfUnderline)
      Environment|=0x20000000;
    if(lf.lfStrikeOut)
      Environment|=0x10000000;
    if(lf.lfCharSet)
      Environment|=0x8000000;
    if(lf.lfOutPrecision)
      Environment|=0x4000000;
    if(lf.lfClipPrecision)
      Environment|=0x2000000;
    if(lf.lfQuality)
      Environment|=0x1000000;
    if(lf.lfPitchAndFamily)
      Environment|=0x800000;

    }//for
    theApp.WriteProfileInt( _T("Default Project"), _T("Settings"), DefaultProject.m_Settings);
    theApp.WriteProfileInt( _T("Default Project"), _T("Break Point"), DefaultProject.m_Break_point);
    theApp.WriteProfileInt( _T("Default Project"), _T("Colors"), DefaultProject.m_Colors);
    theApp.WriteProfileString( _T("Default Project"), _T("AddFile"), DefaultProject.m_AddFile);
    theApp.WriteProfileString( _T("Default Project"), _T("DefFile"), DefaultProject.m_DefFile);
    theApp.WriteProfileString( _T("Default Project"), _T("ExeFileName"), DefaultProject.m_ExeFileName);
    theApp.WriteProfileString( _T("Default Project"), _T("Comments"), DefaultProject.m_Comments);
    theApp.WriteProfileString( _T("Default Project"), _T("GetMethod"), DefaultProject.m_GetMethod);
    theApp.WriteProfileString( _T("Default Project"), _T("PostMethod"), DefaultProject.m_PostMethod);
    theApp.WriteProfileString( _T("Default Project"), _T("ProgArg"), DefaultProject.m_ProgArg);
    theApp.WriteProfileInt( _T("Settings"), _T("Environment"), Environment&0xfff7ffff); // save mode
    {
     CFile file;
     if (file.Open(ProgramPath + _T("Default.sys"), CFile::modeWrite | CFile::modeCreate) )
     {
       CArchive ar(&file, CArchive::store);
       int j=0, i=DefaultProject.m_FilesList.GetSize();

       for (ar<<i; j<i; ar<<DefaultProject.m_FilesList[j++]);
       for (i=0; i<744; ar<<DefaultProject.m_Icon[i++]);
       ar.Close();
       file.Close();
     }
    }
    CString str;
    if (pActivePj && (Environment&32))
      str=pActivePj->GetPathName();
    else if (pActiveFile)
      str=pActiveFile->GetPathName();
    else
      str=_T("");
    if (str!=_T("") && !(Environment&0x4000)) // Remember the last file when exit
      theApp.WriteProfileString( _T("Settings"), _T("Project"), str);
    theApp.WriteProfileInt( _T("Settings"), _T("c_black"), c_black);
    theApp.WriteProfileInt( _T("Settings"), _T("c_red"), c_red);
    theApp.WriteProfileInt( _T("Settings"), _T("c_green"), c_green);
    theApp.WriteProfileInt( _T("Settings"), _T("c_blue"), c_blue);
    theApp.WriteProfileInt( _T("Settings"), _T("c_violet"), c_violet);
    theApp.WriteProfileInt( _T("Settings"), _T("c_output"), c_output);
    theApp.WriteProfileInt( _T("Settings"), _T("synt_color_Comment"), synt_color[0]);
    theApp.WriteProfileInt( _T("Settings"), _T("synt_color_String"), synt_color[1]);
    theApp.WriteProfileInt( _T("Settings"), _T("synt_color_Integer"), synt_color[2]);
    theApp.WriteProfileInt( _T("Settings"), _T("synt_color_Float"), synt_color[3]);
    theApp.WriteProfileInt( _T("Settings"), _T("synt_color_Object"), synt_color[4]);
    theApp.WriteProfileInt( _T("Settings"), _T("synt_color_Operator"), synt_color[5]);
    theApp.WriteProfileInt( _T("Settings"), _T("synt_color_Set_Operator"), synt_color[6]);
    theApp.WriteProfileInt( _T("Settings"), _T("synt_color_Atom"), synt_color[7]);
    theApp.WriteProfileInt( _T("Settings"), _T("synt_color_Functor"), synt_color[8]);
    theApp.WriteProfileInt( _T("Settings"), _T("synt_color_Brackets"), synt_color[9]);
    theApp.WriteProfileInt( _T("Settings"), _T("synt_color_Variable_gl"), synt_color[10]);
    theApp.WriteProfileInt( _T("Settings"), _T("synt_color_Variable_local"), synt_color[11]);
    theApp.WriteProfileInt( _T("Settings"), _T("synt_color_Variable_an"), synt_color[12]);
    theApp.WriteProfileInt( _T("Settings"), _T("synt_color_Error_syntax"), synt_color[13]);

    theApp.WriteProfileInt( _T("Default Project"), _T("STACK_start"), DefaultProject.STACK_start);
    theApp.WriteProfileInt( _T("Default Project"), _T("VARS_start"), DefaultProject.BUDA_start);
    theApp.WriteProfileInt( _T("Default Project"), _T("LINKS_start"), DefaultProject.BUDA_S_start);
    theApp.WriteProfileInt( _T("Default Project"), _T("STACK_max"), DefaultProject.STACK_max);
    theApp.WriteProfileInt( _T("Default Project"), _T("VARS_max"), DefaultProject.BUDA_max);
    theApp.WriteProfileInt( _T("Default Project"), _T("LINKS_max"), DefaultProject.BUDA_S_max);

    CMDIFrameWnd::OnClose();
}

LONG CMainFrame::OnEnd(UINT wParam, LONG lParam) 
{
  // close_all_objects
  //for (DWORD k=0; k<ObjectStore_br; )
  //{
  //  k+=ObjectStore[ObjectStore[k]+2]?ObjectStore[ObjectStore[k]+2]:
  //    (ObjectStore[k]?ObjectStore[k+2]:ObjectStore[k+1]);
  //  if (ObjectStore[k]!=0 && k<ObjectStore_br)
  //    close_object(k);
  //}
  //ObjectStore_br=0;
  
  if (status_fl&64) // Run Directly
  {
    pMainFrame->PostMessage(WM_CLOSE);
    return 1;
  }
  if (wParam)
  {
    status_fl|=1;
    if (ret_fl==1)
      MitiText("Yes.\r\n");
    else if (ret_fl==2)
      MitiText("Stack is full\r\n");
    else if (ret_fl==3)
      MitiText("Terminated: Out of system memory.\r\n");
    //else if (ret_fl==5) nothing
    else if (ret_fl==10)
      MitiText("The program is terminated.\r\n");
  }
  else
  {
    status_fl&=M1^1;
    MitiText("No.\r\n");  
  }
  MitiRedraw();
  status_fl&=M1^2;
#ifdef UNICODE
#if PROF==2
  pMainFrame->SetWindowText(_T("Strawberry Prolog"));
#elif SHAREWARE
  pMainFrame->SetWindowText(_T("Strawberry Prolog (Evaluation copy)"));
#elif PROF==1
  pMainFrame->SetWindowText(_T("Strawberry Prolog (Middle edition)"));
#else    
  pMainFrame->SetWindowText(_T("Strawberry Prolog (Light edition)"));
#endif    
#else  // UNICODE  
#if PROF==2
  pMainFrame->SetWindowText(_T("Strawberry Prolog for 98/Me"));
#elif SHAREWARE
  pMainFrame->SetWindowText(_T("Strawberry Prolog (Evaluation copy for 98/Me)"));
#elif PROF==1
  pMainFrame->SetWindowText(_T("Strawberry Prolog (Middle edition for 98/Me)"));
#else    
  pMainFrame->SetWindowText(_T("Strawberry Prolog (Light edition for 98/Me)"));
#endif    
#endif // UNICODE
  return 1;
}

void CMainFrame::OnUpdateIndicatorLine(CCmdUI *pCmdUI)
{
  pCmdUI->Enable();
  pCmdUI->SetText(m_paneString);
}

LONG CMainFrame::NewIndLine( UINT wParam, LONG lParam)
{
    static int MaxSize=0;
    int nLine, nCol;
    long i, j;
    CChildFrame *pChild;

    if (pChild=(CChildFrame*)MDIGetActive())
    {
      CRichEditCtrl& EditCtrl=
      ((CRichEditView*)(pChild->GetActiveView()))->GetRichEditCtrl();
      EditCtrl.GetSel( i, j );
      nLine=EditCtrl.LineFromChar(j);
      nCol=1+j-EditCtrl.LineIndex(nLine++);
    }
    else
      nLine=nCol=1;
    m_paneString.Format(_T("Ln %d, Col %d"), nLine, nCol);
    CClientDC dc(this);
    if((nLine=dc.GetTextExtent(m_paneString).cx)>MaxSize)
      MaxSize=nLine;
    m_wndStatusBar.SetPaneInfo(1, ID_INDICATOR_LINE, SBPS_NORMAL,MaxSize);
    return 1;
}

void CMainFrame::OnToolsSyntaxColoring()
{
	if(!pActiveFile) return;
  if (status_fl&18) // running or painting
    pActiveFile->m_CharSet|=0x180;
  else
  {
    pActiveFile->m_CharSet|=0x80;
    pMainFrame->SyntaxColoring(59); // 59 is the read Flag
  }
}
void CMainFrame::OnToolsHideSyntaxColoring()
{
	if(!pActiveFile) return;
  pActiveFile->m_CharSet&=0xfffffc7f;
  pMainFrame->SyntaxColoring(1);
}

static DWORD CALLBACK MyStreamOutCallback2(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
  DWORD i, j, read, code;
  
  for( i=0; pbBuff[i]<128 && i< (DWORD)cb; i++);
  for( j=i; j< (DWORD)cb; i++)
  {
    if (pbBuff[j]<128)
      pbBuff[i]=pbBuff[j++];
    else
    {
      j+=read=readUTF8(pbBuff + j, &code);
      if (read==0) // error
      {
        j++;
        pbBuff[i]=(BYTE)default_char; //'#'
      }
      else if ((code=char_set(code, 0, ch_set))==0)
        pbBuff[i]=(BYTE)default_char; //'#'
      else
        pbBuff[i]= (BYTE)code;
    }
  }
  CFile* pFile = (CFile*) dwCookie;
  pFile->Write(pbBuff, i);
  *pcb = cb;
  return 0;
}
static DWORD CALLBACK MyStreamOutCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
  CFile* pFile = (CFile*) dwCookie;
  pFile->Write(pbBuff, cb);
  *pcb = cb;
  return 0;
}

static DWORD CALLBACK MyStreamInCallback(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{ // dwCookie 0,1 - black 2,3 colorful, 0,2 from file 1,3 from window
  static DWORD j=0, t=0, rest=0;
  DWORD i, read, code, end, cb2=min(cb, 2*BUFFERS)-rest;

  if (j==t || rest)
  {
    if (dwCookie)
      end = pGFile->Read(pbBuff+rest, cb2);
    else 
      end = pAr->Read(pbBuff+rest, cb2);
    if (rest)
    {
      end+=rest;
      for(i=0; i<rest; pbBuff[i]=MyCallback1[j+i], i++);
      rest=0;
    }
    if (dwCookie<2 && (dwCookie==1 || ch_set==0))
    {
      *pcb = end;
      return 0;
    }
    if ((gl_flag&1) && pbBuff[0]<128)
    {
      gl_flag&=0xfffe;
      for(i=end; i--; pbBuff[i+4]=pbBuff[i]);
      i=5; end+=4; pbBuff[0]='\\'; pbBuff[1]='f'; pbBuff[2]='0'; pbBuff[3]=' ';
    }
    else
      i=0;
    for( ; i<end && pbBuff[i]<128; i++);
    for(j=i; j<end; MyCallback1[j-i]=pbBuff[j], j++);
    MyCallback1[t=end-i]=0;
    j=0;
  }
  else
    i=0;
  for(; i<(DWORD)(cb-16) && j<t; j++)
  {
    if ((BYTE)(MyCallback1[j])<128) 
    {
      if (gl_flag&1) // && ch_set==1
      {
        gl_flag&=0xfffe;
        i+=sprintf((char*)(pbBuff + i), "\\f0 ");
      }
      pbBuff[i++]=MyCallback1[j];
    }
    else if (ch_set==0)
    {
      read=readUTF8(MyCallback1 + j, &code);
      if (read==0) // error
      {
        if (t-j>5 || i==0)
        {
          pbBuff[i++]=(BYTE)default_char; //'#'
          gl_flag|=4;
        }
        else
        {
          rest=t-j;
          break;
        }
      }
      else
      {
        if (ch_set==0)
        {
          i+=sprintf((char*)(pbBuff + i), "\\u%d?", code); // dwCookie==2 || ==3
          if (code>=0x10000)
            gl_flag|=8;
        }  
        else if ((code=char_set(code, 0, ch_set))==0)
        {
          pbBuff[i++]=(BYTE)default_char; //'#'
          gl_flag|=2;
        }
        else
        {
          if (!(gl_flag&1) && ch_set==1)
          {
            gl_flag|=1;
            i+=sprintf((char*)(pbBuff + i), "\\f1 ");
          }
          i+=sprintf((char*)(pbBuff + i), "\\\'%x", code);
        }
        j+=read-1;
      }
    }
    else if (dwCookie) // ==2 || ==3
    {
      if ((code=MAP_CP[ch_set-1][(BYTE)(MyCallback1[j])-128])==0)
      {
        pbBuff[i++]=(BYTE)default_char; //'#'
        gl_flag|=2;
      }
      else if (ch_set>2)
        i+=sprintf((char*)(pbBuff + i), "\\u%d?", code);
      else
      {
        if (!(gl_flag&1) && ch_set==1)
        {
          gl_flag|=1;
          i+=sprintf((char*)(pbBuff + i), "\\f1 ");
        }
        i+=sprintf((char*)(pbBuff + i), "\\\'%x", (BYTE)(MyCallback1[j]));
      }
    }
    else  // ch_set>0, dwCookie==0
    {
      if ((code=MAP_CP[ch_set-1][(BYTE)(MyCallback1[j])-128])==0)
      {
        pbBuff[i++]=(BYTE)default_char; //'#'
        gl_flag|=2;
      }
      else
        i+=unicodeToUTF8(code, (unsigned char*)(pbBuff + i));
    }
  }
  // pbBuff[i]=0; // maybe will help to stop MS bugs // but it is the same
  *pcb = i;
  return 0;
}

void CMainFrame::SyntaxColoring(DWORD Flag)
{
  DWORD i;
  EDITSTREAM es;

  if (!pActiveFile || pActiveFile->m_FileType==4 || pActiveFile->m_FileType==7)
    return;
  if (Environment&0x80000) // save mode
  {
    if (Flag==59)
      Flag=1;
    else if (Flag==61)
      Flag=0;
  }
  if (status_fl&18) // running or painting
  {
    if (Flag==59)
      return;
    else if (Flag==61)
    {
      pActiveFile->m_CharSet=0x180;
      Flag=0;
    }
  }
  else if (Flag==0)
    pActiveFile->m_CharSet=0;
  if (Flag==1 || Flag==59)
  {
    ch_set=pActiveFile->m_CharSet&63;
    default_char=(pActiveFile->m_CharSet&64)?'#':'?';
    pActiveFile->m_CharSet&=0xfffffcff;
  }
  else if (gl_open&4)
  {
    ch_set=(gl_open&0x7e0000)/0x20000;
    default_char=(gl_open&0x10000)?'#':'?';
    if (pActiveFile->m_FileType==1)
    {
      pActiveFile->m_pInfo->m_Settings&=M1^0x7f0000;
      pActiveFile->m_pInfo->m_Settings|=0x20000*ch_set+0x10000*(default_char=='#');
    }
  }
  else
  {
    ch_set=(pActiveFile->m_pInfo->m_Settings&0x7e0000)/0x20000;
    default_char=(pActiveFile->m_pInfo->m_Settings&0x10000)?'#':'?';
  }
  CRichEditCtrl *pEdit=&(pActiveFile->GetView()->GetRichEditCtrl());
  gl_flag=0;
  if (Flag==0)
  {
    pActiveFile->m_CharSet|=ch_set+64*(default_char=='#');
    es.dwCookie = 0;
    es.pfnCallback = MyStreamInCallback; 
    pEdit->StreamIn((CP_UTF8 << 16) | SF_USECODEPAGE | SF_TEXT, es);
FinishAll:
    if (gl_flag&14)
    {
      CString ch_set_str=_T("");
      sprintf(string2,"\n\nThe errors are replaced with the symbol \'%c\'.", default_char);
      if (gl_flag&2)
      {
        ch_set_str+="In this file there are symbols which cannot fit in the char set:\n";
        ch_set_str+=Char_Sets[ch_set];
        ch_set_str+=string2;
      }
      else if (gl_flag&4)
      {
        ch_set_str+="This file is not correct Unicode file.";
        ch_set_str+=string2;
      }
      else
        ch_set_str+="This file contains Unicode symbols which are bigger than two bytes (bigger than 0xFFFF). Maybe this is not a correct Unicode file.";
      MessageBox(ch_set_str, _T("Something is wrong"), MB_ICONWARNING | MB_OK);
    }
    return;
  }
  HANDLE hTempFile1, hTempFile2;
  i=GetEnvironmentVariable(_T("TEMP"), string3, MAX_PATH);
  if(i > 0)
  {
    my_strcpy(string3+i, _T("\\Temp7sp1.tmp"));
    hTempFile1 = CreateFile(string3, GENERIC_READ | GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
    if (hTempFile1!=INVALID_HANDLE_VALUE)
    {
      string3[i+8]='2';
      hTempFile2 = CreateFile(string3, GENERIC_READ | GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
    }
  }
  else
    hTempFile1=INVALID_HANDLE_VALUE;
  if (hTempFile1==INVALID_HANDLE_VALUE)
  {
    hTempFile1 = CreateFile(ProgramPath+_T("Temp7sp1.tmp"), GENERIC_READ | GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
    if (hTempFile1!=INVALID_HANDLE_VALUE)
      hTempFile2 = CreateFile(ProgramPath+_T("Temp7sp2.tmp"), GENERIC_READ | GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);  
    else
    {
      hTempFile1 = CreateFile(_T("C:\\Temp7sp1.tmp"), GENERIC_READ | GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
      hTempFile2 = CreateFile(_T("C:\\Temp7sp2.tmp"), GENERIC_READ | GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
    }
  }
  if (hTempFile1==INVALID_HANDLE_VALUE || hTempFile2==INVALID_HANDLE_VALUE)
  {
    MessageBox(_T("Cannot open a temporal file. Maybe the Strawberry Prolog directory and C:\\ are both write protected."), _T("Syntax Coloring"), MB_OK | MB_ICONSTOP);
    return;
  }
  CFile TempFile1(hTempFile1);
  CFile TempFile2(hTempFile2);
  CHARRANGE Selection;
  int Empty_Buffer, Not_Modified, EventMask;
  if (Flag!=61)
  {
    pEdit->GetSel(Selection);
    Empty_Buffer=(pEdit->CanUndo())?0:1;
    Not_Modified=(pActiveFile->IsModified())?0:1;
    EventMask=pEdit->SetEventMask(ENM_NONE);
    pEdit->SetOptions(ECOOP_XOR, ECO_AUTOVSCROLL);
    pEdit->SetOptions(ECOOP_XOR, ECO_AUTOHSCROLL);
    pEdit->HideSelection(TRUE, FALSE);
    pEdit->SetSel(0, M1);
    es.dwCookie = (DWORD) &TempFile1;
    if (Flag==1 || ch_set==0)
      es.pfnCallback = MyStreamOutCallback;
    else
      es.pfnCallback = MyStreamOutCallback2;
    pEdit->StreamOut((CP_UTF8 << 16) | SF_USECODEPAGE | SF_TEXT | SFF_SELECTION, es);
    TempFile1.Seek(0, CFile::begin);
    pGFile= &TempFile1; // for Flag==1 and for Flag==59
    if (Flag==1)
    {
      CHARFORMAT cf;
#if PROF
      if (pActiveFile->m_FileType==6) // Add file
#else
      if (pActiveFile->m_FileType==6 || pActiveFile->m_pInfo->m_Settings&512) // Add file or Not for Light
#endif
        cf.crTextColor=c_green;
      else
        cf.crTextColor=pActiveFile->m_pInfo->m_Colors;
      cf.dwMask=CFM_COLOR;
      cf.dwEffects=0;
      es.pfnCallback = MyStreamInCallback;
      es.dwCookie = 1;
      pEdit->SetSelectionCharFormat(cf);
      pEdit->StreamIn((CP_UTF8 << 16) | SF_USECODEPAGE | SF_TEXT | SFF_SELECTION, es);  // SFF_SELECTION for undo
      goto FinishSyntCol;
    }
  }
  {
  CArchive ar2(&TempFile2, CArchive::store);
  //  if (ch_set==1) deflang1026
  ar2.Write("{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1026{\\fonttbl{\\f0\\fnil\\fprq12\\fcharset0 ", 77); // 1033
  ar2.Write(make_short(pActiveFile->m_pInfo->m_lf.lfFaceName), my_strlen(pActiveFile->m_pInfo->m_lf.lfFaceName)); // "Courier New"
  ar2.Write(";}{\\f1\\fnil\\fprq12\\fcharset204 ", 31);
  ar2.Write(make_short(pActiveFile->m_pInfo->m_lf.lfFaceName), my_strlen(pActiveFile->m_pInfo->m_lf.lfFaceName)); // "Courier New"
  ar2.Write(";}}\n{\\colortbl ;", 16);
  for (i=0; i<LAST_COLOR; i++)
  {
    sprintf(string2, "\\red%d\\green%d\\blue%d;",
      synt_color[i]&0xff, (synt_color[i]&0xff00) >> 8, (synt_color[i]&0xff0000) >> 16);
    ar2.Write(string2, strlen(string2));
  }
  int fh=pActiveFile->m_pInfo->m_lf.lfHeight;
  if (fh<0)
    fh= (-fh*14)/9;
  else if (fh==0)
    fh=22;
  else    
    fh= (fh*14)/9;
  sprintf(string2, "}\n\\viewkind4\\uc1\\pard\\f0\\fs%d", fh); // 22
  ar2.Write(string2, strlen(string2));
  status_fl|=16; // painting
  if (pCompiled==NULL)  
  {
    pActive=pActiveFile;
    pActiveCtrl=NULL;
    pInfo2=pActiveFile->m_pInfo;
    // if add and def are missing
    ArType[0]=124; Array[0]=ReadStack[0]=Left[0]=0; Right[0]=1;
    if (Flag==61)
      compile(4);
    else
    {
      my_strcpy(namef, pActiveFile->GetPathName());
      compile(4);
    }
    //if (error) // Standard.add makes error!
    //{
    //  ar2.Close();
    //  TempFile1.Close();
    //  TempFile2.Close();
    //  MitiText("Syntax coloring problem:\r\nSomething is wrong with your Standard.add and Standard.def files.\r\n\r\n", &cf_red);
    //  return;
    //}
  }
  else
  {
    sv_StStore=512;
  }
  error=1;
  //CHARFORMAT2 cf_SyntaxColor;
  //cf_SyntaxColor.dwMask=CFM_COLOR ; // | CFM_BACKCOLOR
  ////cf_SyntaxColor.crBackColor=RGB(255,200,200);
  //cf_SyntaxColor.dwEffects=0;

  pAr2=&ar2;
  DWORD not_used;
  f_end=i_poin=read_br=newline_br=0;
  string[0]=0;
  read_n(&not_used, Flag);
  //while(f_end && f_end!=M1);

  status_fl&=M1^16;
  if (Flag==61)
    ar2.Write("\\par\n}", 6);
  else 
    ar2.Write("\n}", 2); 
  //ar2<<"}";  // this has to be missed because kills the last enter in open
  ar2.Close();
  }
  TempFile2.Seek(0, CFile::begin);
  pGFile= &TempFile2;
  es.pfnCallback = MyStreamInCallback; 
  if (Flag==61)
  {
    pActiveFile->m_CharSet=128+ch_set+64*(default_char=='#');
    es.dwCookie = 2;
    pEdit->StreamIn(SF_RTF, es); // no help SF_NCRFORNONASCII
    //CArchive ar3(&TempFile, CArchive::load);
    //pActiveFile->CRichEditDoc::Serialize(ar3);
    //ar3.Close();
  }
  else
  {
    es.dwCookie = 3;
    pEdit->StreamIn(SF_RTF | SFF_SELECTION, es);  // SFF_SELECTION for undo
FinishSyntCol:
    pEdit->SetSel(Selection);
    pEdit->HideSelection(FALSE, FALSE);
    pEdit->SetOptions(ECOOP_XOR, ECO_AUTOVSCROLL);
    pEdit->SetOptions(ECOOP_XOR, ECO_AUTOHSCROLL);
    pEdit->SetEventMask(EventMask);
    if (Empty_Buffer)
      pEdit->EmptyUndoBuffer();
    if (Not_Modified)
      pActiveFile->SetModifiedFlag(FALSE);
  }
  TempFile1.Close();
  TempFile2.Close();
  goto FinishAll;
}
