// CEdtX.cpp : implementation file
//
// Written by John A deLaubenfels, https://www.adaptune.com/steg.htm .
// Permission granted to use freely in any non-fraudulent way.
//
//

#include "pch.h"
#include "Steg2.h"
#include "CEdtX.h"
#include "ShowtxtDlg.h"   // qxl: just for FindDlg.
#include "ssprint.h"

#pragma warning( disable : 4996 )



// CEdtX

IMPLEMENT_DYNAMIC(CEdtX, CEdit)

CEdtX::CEdtX(): m_bSensitive(false), m_pCommonInfo(NULL)
{

}

CEdtX::~CEdtX()
{
}


BEGIN_MESSAGE_MAP(CEdtX, CEdit)
END_MESSAGE_MAP()



// CEdtX message handlers




BOOL CEdtX::PreTranslateMessage(MSG* pMsg) {
   // TODO: Add your specialized code here and/or call the base class

   // Intercept Ctrl + Z (Undo), Ctrl + X (Cut), Ctrl + C (Copy), Ctrl + V (Paste) and Ctrl + A (Select All)
   // before CEdit base class gets a hold of them.
   if (pMsg->message == WM_KEYDOWN && ::GetKeyState(VK_CONTROL) < 0) {
      switch (pMsg->wParam) {
         case 'Z':
            Undo();
            return TRUE;
         case 'X':
            Cut();
            return TRUE;
         case 'C':
            Copy();
            return TRUE;
         case 'V':
            Paste();
            return TRUE;
         case 'A':
            SetSel(0, -1);
            return TRUE;
         case 'F':
            doFind();
            return TRUE;
         case 'N':
            doFnext();
            return TRUE;
         case 'P':
            doFprev();
            return TRUE;
         case 'S':
            doSave();
            return TRUE;
      } // switch (pMsg->wParam)
   } // if (pMsg->message == WM_KEYDOWN && ::GetKeyState(VK_CONTROL) < 0) {

   return CEdit::PreTranslateMessage(pMsg);
}




// qxdoFind()

void CEdtX::doFind() {
   m_searchIndex         = 0;
   int nStart, nEnd;
   this->GetSel(nStart, nEnd);
   m_searchIndex = nStart + 1;


   FindDlg dlgFind;
   // dlgFind.m_ssBanner    = "Find and search for";
   dlgFind.m_pCommonInfo = NULL;   // m_pCommonInfo;
   dlgFind.m_ssFind      = "";
   dlgFind.m_bCaseSens   = m_bSensitive;

   long long ill = dlgFind.DoModal();

   if(ill == IDOK) {
      m_bSensitive = dlgFind.m_bCaseSens;
      m_ssKeepFind = dlgFind.m_ssFind;
      CString cs;
      this->GetWindowText(cs);
      std::string ssBig = (const char *)cs;

      std::string ssDoFind = m_ssKeepFind;

      if(!m_bSensitive) {
         doLwc(ssBig);
         doLwc(ssDoFind);
      } // if(!m_bSensitive)

      int lenFind = (int)m_ssKeepFind.size();

      int ij = (int)ssBig.find(ssDoFind, m_searchIndex);
      if(ij == (int)std::string::npos) {
         // can we start over?

         int ik = (int)ssBig.find(ssDoFind, 0);
         if(ik == (int)std::string::npos) {
            // string doesn't exist anywhere in the text:
            std::string ssMsg;
            ssprint(ssMsg, "\"%s\" not found.", m_ssKeepFind.c_str());
            AfxMessageBox(ssMsg.c_str());

            m_searchIndex = 0;
         } else {
            // found it when we started over.
            int iStart = ik;
            int iEnd   = ik + lenFind;
            this->SetSel(iStart, iEnd);

            m_searchIndex = iEnd;
         } // if(ik == (int)std::string::npos)
      } else {
         int iStart = ij;
         int iEnd   = ij + lenFind;
         this->SetSel(iStart, iEnd);

         m_searchIndex = iEnd;
      } // !if(ij == std::string::npos)

   } // if(ill == IDOK)

   this->SetFocus();
} // void CEdtX::doFind() {






// qxdoFnext()

void CEdtX::doFnext() {
   CString cs;
   this->GetWindowText(cs);
   std::string ssBig = (const char *)cs;

   std::string ssDoFind = m_ssKeepFind;

   if(!m_bSensitive) {
      doLwc(ssBig);
      doLwc(ssDoFind);
   } // if(!m_bSensitive)

   int lenFind = (int)m_ssKeepFind.size();

   int ij = (int)ssBig.find(ssDoFind, m_searchIndex);
   if(ij == (int)std::string::npos) {
      // can we start over?

      int ik = (int)ssBig.find(ssDoFind, 0);
      if(ik == (int)std::string::npos) {
         // string doesn't exist anywhere in the text:
         std::string ssMsg;
         ssprint(ssMsg, "\"%s\" not found.", m_ssKeepFind.c_str());
         AfxMessageBox(ssMsg.c_str());

         m_searchIndex = 0;
      } else {
         // found it when we started over.
         int iStart = ik;
         int iEnd   = ik + lenFind;
         this->SetSel(iStart, iEnd);

         m_searchIndex = iEnd;
      } // if(ik == (int)std::string::npos)
   } else {
      int iStart = ij;
      int iEnd   = ij + lenFind;
      this->SetSel(iStart, iEnd);

      m_searchIndex = iEnd;
   } // !if(ij == std::string::npos)

   this->SetFocus();
} // void CEdtX::doFnext() {






// qxdoFprev()

void CEdtX::doFprev() {
   CString cs;
   this->GetWindowText(cs);
   std::string ssBig = (const char *)cs;

   std::string ssDoFind = m_ssKeepFind;

   if(!m_bSensitive) {
      doLwc(ssBig);
      doLwc(ssDoFind);
   } // if(!m_bSensitive)

   int lenFind = (int)m_ssKeepFind.size();

   int ij = (int)ssBig.rfind(ssDoFind, (m_searchIndex - lenFind - 1));
   if(ij == (int)std::string::npos) {
      // can we start over?

      int ik = (int)ssBig.rfind(ssDoFind, -1);
      if(ik == (int)std::string::npos) {
         // string doesn't exist anywhere in the text:
         std::string ssMsg;
         ssprint(ssMsg, "\"%s\" not found.", m_ssKeepFind.c_str());
         AfxMessageBox(ssMsg.c_str());

         m_searchIndex = 0;
      } else {
         // found it when we started over.
         int iStart = ik;
         int iEnd   = ik + lenFind;
         this->SetSel(iStart, iEnd);

         m_searchIndex = iEnd;
      } // if(ik == (int)std::string::npos)
   } else {
      int iStart = ij;
      int iEnd   = ij + lenFind;
      this->SetSel(iStart, iEnd);

      m_searchIndex = iEnd;
   } // !if(ij == std::string::npos)

   this->SetFocus();
} // void CEdtX::doFprev() {






// qxdoSave()

void CEdtX::doSave() {
   LPCTSTR pcFilter = _T("Text Files (*.txt)|*.txt||");
   DWORD dwFlags = OFN_OVERWRITEPROMPT;

   CFileDialog dlgSav(FALSE, NULL, NULL, dwFlags, pcFilter);

   dlgSav.m_ofn.lpstrTitle  = "Save to file.";

   if(m_pCommonInfo->ssMessageLoc.size() > 0)
      dlgSav.m_ofn.lpstrInitialDir  = m_pCommonInfo->ssMessageLoc.c_str();

   long long ill = dlgSav.DoModal();

   if(ill == IDOK) {

      CString csFileName = dlgSav.GetFileName();
      std::string ssFileName = (const char *)(LPCTSTR)csFileName;

      CString csPathName = dlgSav.GetPathName();
      std::string ssPathName = (const char *)(LPCTSTR)csPathName;

      SMARTA(pcFull, char, (ssPathName.size()+32), smaFull);
      SMARTA(pcBody, char, (ssPathName.size()+32), smaBody);
      SMARTA(pcDott, char, (ssPathName.size()+32), smaDott);
      SMARTA(pcExtt, char, (ssPathName.size()+32), smaExtt);
      SMARTA(pcNuu,  char, (ssPathName.size()+32), smaNuu);

      break_file_name(ssPathName.c_str(), pcBody, pcDott, pcExtt);

      sprintf(pcNuu, "%s%s", pcBody, ".txt");

      arcMeDotty(pcNuu);

      FILE *fpOut = NULL;
      errno_t err = 0;
      if((err = fopen_s(&fpOut, pcNuu, "w")) == 0) {
         CString cs;
         this->GetWindowText(cs);
         std::string ssBigString = (const char *)cs;

         ssBigString = rmCr(ssBigString);

         fprintf(fpOut, "%s", ssBigString.c_str());

         fclose(fpOut); fpOut=NULL;

         SMARTA(pcDir, char, (ssPathName.size()+32), smaDir);
         SMARTA(pcFil, char, (ssPathName.size()+32), smaFil);

         cut_file_name(ssPathName.c_str(), pcDir, pcFil);

         m_pCommonInfo->ssMessageLoc = pcDir;

      } else {
         // char cbuf[256];
         // sprintf(cbuf, "We got error %d.\n", err);
         // doThing(cbuf);
      } // !if((err = fopen_s(&fpOut, pcNuu, "w")) == 0)
   } // if(ill == IDOK)

   this->SetFocus();
} // void CEdtX::doSave() {










