/* 
   Copyright 2001-2003 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.  

   You may contact the author at:

   mailto::camille@bluegrass.net

   or by snail mail at:

   David Lindauer
   850 Washburn Ave Apt 99
   Louisville, KY 40222
**********************************************************************

FIF.C holds the find-in-file functionality

**********************************************************************
*/
#include <windows.h>
#include <commctrl.h>
#include <dir.h>
#include <stdio.h>
#include "header.h"

extern HINSTANCE hInstance ;
extern HWND hwndError, hwndFrame ;

char *fifhistory[MAX_COMBO_HISTORY] ;

static int fifwindow,regexp,casesens,type ;
static char defdir[256],deffile[256] ;
static char dir[512],find[512] ;
static char *fifdirhistory[MAX_COMBO_HISTORY] ;
static char filelists[10][5][10] = {
   { "*.cpp","*.hpp","*.c","*.h" } ,
   { "*.asm" },
   { "*.rc", "*.def" },
   { "*.txt" },
   { "*.*" } ,
} ;

LRESULT CALLBACK fifDirDlgProc(HWND hwnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
   static char curdir[256] ;
   char buf[256] ;
   int sel ;
   HWND child ;
   switch (iMessage) {
      case WM_INITDIALOG:
         strcpy(curdir,defdir) ;
         strcpy(buf,curdir) ;
         if (buf[strlen(buf)-1] != '\\')
            strcat(buf,"\\") ;
         strcat(buf,"*.*") ;
         SendDlgItemMessage(hwnd,1137,CB_DIR,DDL_DRIVES|DDL_EXCLUSIVE,(LPARAM)"*") ;
         SendDlgItemMessage(hwnd,1121,LB_DIR,DDL_DIRECTORY|DDL_EXCLUSIVE,(LPARAM)buf) ;
         SendDlgItemMessage(hwnd,1120,LB_DIR,DDL_READWRITE,(LPARAM)buf) ;
         sprintf(buf,"[-%c-]",tolower(curdir[0]));
         SendDlgItemMessage(hwnd,1137,WM_SETTEXT,0,(LPARAM)buf) ;
         SendDlgItemMessage(hwnd,1138,WM_SETTEXT,0,(LPARAM)curdir) ;
         child = GetDlgItem(hwnd,1138) ;
         EnableWindow(child,0);
         break ;
      case WM_COMMAND:
         switch(wParam) {
            case IDOK: // + 1152 - edit
               strcpy(defdir,curdir) ;
               SendDlgItemMessage(hwnd,1137,WM_GETTEXT,256,(LPARAM)deffile) ;
               EndDialog(hwnd,1) ;
               break ;
            case IDCANCEL:
               EndDialog(hwnd,0) ;
               break ;
            default:
               switch(HIWORD(wParam)) {
                  case CBN_SELCHANGE:
                     switch(LOWORD(wParam)) {
                        case 1137: /* drives */
                           sel = SendDlgItemMessage(hwnd,1137,CB_GETCURSEL,0,0) ;
                           SendDlgItemMessage(hwnd,1137,CB_GETLBTEXT,sel,(LPARAM)buf) ;
                           getcurdir(toupper(buf[2])-0x40,curdir+3) ;
                           curdir[0] = buf[2] ;
                           curdir[1] = ':' ;
                           curdir[2] = '\\' ;
                           strcpy(buf,curdir) ;
                           if (buf[strlen(buf)-1] != '\\')
                              strcat(buf,"\\") ;
                           strcat(buf,"*.*") ;
                           SendDlgItemMessage(hwnd,1121,LB_RESETCONTENT,0,0) ;
                           SendDlgItemMessage(hwnd,1120,LB_RESETCONTENT,0,0) ;
                           SendDlgItemMessage(hwnd,1121,LB_DIR,DDL_DIRECTORY|DDL_EXCLUSIVE,(LPARAM)buf) ;
                           SendDlgItemMessage(hwnd,1120,LB_DIR,DDL_READWRITE,(LPARAM)buf) ;
                           SendDlgItemMessage(hwnd,1138,WM_SETTEXT,0,(LPARAM)curdir) ;
                           deffile[0] = 0 ;
                           SendDlgItemMessage(hwnd,1152,WM_SETTEXT,0,(LPARAM)"") ;
                           break ;
                        case 1121: /* dir */
                           sel = SendDlgItemMessage(hwnd,1121,LB_GETCURSEL,0,0) ;
                           SendDlgItemMessage(hwnd,1121,LB_GETTEXT,sel,(LPARAM)buf) ;
                           if (buf[1] == '.' && buf[2] == '.') {
                              char *p = curdir + strlen(curdir) - 1 ;

                              if (*p == '\\' )
                                 p-- ;
                              while (p > curdir && *p != '\\')
                                 p-- ;
                              *p = 0 ;
                                           
                           } else {
                              if (buf[strlen(curdir)-1] != '\\')
                                 strcat(curdir,"\\") ;
                              strcat(curdir,buf+1) ;
                              curdir [strlen(curdir)-1] = 0 ;
                           }
                           strcpy(buf,curdir) ;
                           if (buf[strlen(buf)-1] != '\\')
                              strcat(buf,"\\") ;
                           strcat(buf,"*.*") ;
                           SendDlgItemMessage(hwnd,1121,LB_RESETCONTENT,0,0) ;
                           SendDlgItemMessage(hwnd,1120,LB_RESETCONTENT,0,0) ;
                           SendDlgItemMessage(hwnd,1121,LB_DIR,DDL_DIRECTORY|DDL_EXCLUSIVE,(LPARAM)buf) ;
                           SendDlgItemMessage(hwnd,1120,LB_DIR,DDL_READWRITE,(LPARAM)buf) ;
                           SendDlgItemMessage(hwnd,1137,WM_SETTEXT,0,(LPARAM)buf) ;
                           SendDlgItemMessage(hwnd,1138,WM_SETTEXT,0,(LPARAM)curdir) ;
                           deffile[0] = 0 ;
                           SendDlgItemMessage(hwnd,1152,WM_SETTEXT,0,(LPARAM)"") ;
                           break ;
                        case 1120: /* file */
                           sel = SendDlgItemMessage(hwnd,1120,LB_GETCURSEL,0,0) ;
                           SendDlgItemMessage(hwnd,1120,LB_GETTEXT,sel,(LPARAM)buf) ;
                           SendDlgItemMessage(hwnd,1152,WM_SETTEXT,0,(LPARAM)buf) ;
                           break ;
                     }
                     break ;
               }
               break ;
         }
         break ;
      case WM_CLOSE:
         EndDialog(hwnd,0) ;
         break ;
   }
   return 0 ;
}
LRESULT CALLBACK fifDlgProc(HWND hwnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
   HWND child ;
   char buf[256] ;
   switch(iMessage) {
      case WM_INITDIALOG:
         deffile[0] = 0 ;
         strcpy(defdir,(char *)ProfileToString("ProjDir",getcwd(buf,256))) ;
         child = GetDlgItem(hwnd,1152) ; // find what init
         SubClassHistoryCombo(child) ;
         SendMessage(child,WM_SETHISTORY,0,(LPARAM)fifhistory) ;
         child = GetDlgItem(hwnd,1153) ; // in dir init
         SubClassHistoryCombo(child) ;
         SendMessage(child,WM_SETHISTORY,0,(LPARAM)fifdirhistory) ;
         SetWindowText(child,defdir) ;
         AddComboString(hwnd,1154,"C files (*.cpp; *.c; *.hpp; *.h)") ;
         AddComboString(hwnd,1154,"Assembly files (*.asm)") ;
         AddComboString(hwnd,1154,"Resource files (*.rc; *.def)") ;
         AddComboString(hwnd,1154,"Text files (*.txt)") ;
         AddComboString(hwnd,1154,"All files (*.*)") ;
         SetComboSel(hwnd,1154,0) ;
         SetCBField(hwnd,1040,0) ;      // regexp
         SetCBField(hwnd,1041,0) ;      // case sens
         SetCBField(hwnd,1042,0) ;      // window 2
         break ;
      case WM_COMMAND:
         switch(wParam) {
            case 1: /* idok */
               child = GetDlgItem(hwnd,1152) ;
               SendMessage(child,WM_SAVEHISTORY,0,0) ;
               SendMessage(child,WM_GETTEXT,256,(LPARAM)find) ;
               child = GetDlgItem(hwnd,1153) ;
               SendMessage(child,WM_SAVEHISTORY,0,0) ;
               SendMessage(child,WM_GETTEXT,256,(LPARAM)dir) ;
               
               type = GetComboSel(hwnd,1154) ;

               regexp = GetCBField(hwnd,1040) ;
               casesens = GetCBField(hwnd,1041) ;
               fifwindow = GetCBField(hwnd,1042) ? ERR_FIND2_WINDOW : ERR_FIND1_WINDOW ;
               EndDialog(hwnd,1) ;
               break ;
            case 2: /* idcancel */
               EndDialog(hwnd,0) ;
               break ;
            case 100: /* browse */
               if (DialogBox(hInstance,"DIRDLG",GetParent(hwnd),(DLGPROC)&fifDirDlgProc)) {
                  SendDlgItemMessage(hwnd,1153,WM_SETTEXT,0,(LPARAM)defdir) ;   
               }
               break ;
         }
         break ;
   }
   return 0 ;
}
void FindInFilesThread(voud)
{
   if (DialogBox(hInstance,"FINDINFILESDLG",hwndFrame,(DLGPROC)&fifDlgProc)) {
      char args[256] ;
      char current[512] ;
      int i = 0 ;
      SendMessage(hwndError, WM_SELERRWINDOW,0,fifwindow) ;
      sprintf(args,"-n%s%s",!casesens ? "y" : "", !regexp ? "i" : "") ;
      if (dir[strlen(dir)-1] != '\\')
         strcat(dir,"\\") ;

      if (deffile[0]) {
         sprintf(current,"grep %s \"%s\" %s%s",args,find,dir,deffile) ;
         Execute("grep.exe",current,fifwindow) ;
         Execute("grep.exe",dir,fifwindow) ;
      } else while (TRUE) {
         if (filelists[type][i][0] == 0)
            break ;
         sprintf(current,"grep %s \"%s\" %s%s",args,find,dir,filelists[type][i]) ;
         Execute("grep.exe",current,fifwindow) ;
         i++ ;
      }
      SendMessage(hwndError,WM_ERRDONESCAN,0,fifwindow) ;
   }
}
void FindInFiles(void)
{
   DWORD threadhand ;
   CreateThread(0,0,(LPTHREAD_START_ROUTINE)FindInFilesThread,0,0,&threadhand) ;
}