/* 
CCIDE
Copyright 2001-2011 David Lindauer.

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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

You may contact the author at:
	mailto::camille@bluegrass.net
 */
#include <windows.h>
#include <commctrl.h>
#include <dir.h>
#include <stdio.h>
#include "header.h"

extern HINSTANCE hInstance;
extern HWND hwndFrame;
extern char szWorkspaceName[];
extern char *findhist[MAX_COMBO_HISTORY];

char *fifdirhist[MAX_COMBO_HISTORY];

static int fifwindow, regexp, casesens, subdirs, type, wholewords;
static char defdir[256], deffile[256];
static char dir[512], find[512];
static char filelists[10][10][10] = 
{
    {
        "*.cpp", "*.hpp", "*.cxx", "*.hxx", "*.c", "*.h", "*.p"
    }
    , 
    {
        "*.asm", "*.asi", "*.inc"
    }
    , 
    {
        "*.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, "*.*");
			ShowWindow(GetDlgItem(hwnd, 1090), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, 1152), SW_HIDE);
			ShowWindow(GetDlgItem(hwnd, 1120), SW_HIDE);
            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];
	PROJLIST *selectedProject;
    switch (iMessage)
    {
        case WM_INITDIALOG:
            deffile[0] = 0;
			selectedProject = ProjectFindSelectedEXE(0);
			if (selectedProject)
			{
				char *p;
	            strcpy(defdir, selectedProject->name);
				p = strrchr(defdir, '\\');
				if (p)
					p[1] = 0;
			}
			else
			{
				GetCurrentDirectory(sizeof(defdir), defdir); 
			}
            child = GetDlgItem(hwnd, 1152); // find what init
            SubClassHistoryCombo(child);
            SendMessage(child, WM_SETHISTORY, 0, (LPARAM)findhist);
            child = GetDlgItem(hwnd, 1153); // in dir init
            SubClassHistoryCombo(child);
            SendMessage(child, WM_SETHISTORY, 0, (LPARAM)fifdirhist);
            SetWindowText(child, defdir);
            AddComboString(hwnd, 1154, 
                "C files (*.cpp; *.cxx; *.c; *.hpp; *.hxx; *.h; *p)");
            AddComboString(hwnd, 1154, "Assembly files (*.asm; *.asi; *.inc)");
            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;
				subdirs = GetCBField(hwnd, 1043);
				wholewords = GetCBField(hwnd, 1044);
                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;
}

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

static int hasFiles(char *path, char *ext)
{
    WIN32_FIND_DATA x;
    char buf[265];
    HANDLE h;
    sprintf(buf, "%s%s", path, ext);
    h = FindFirstFile(buf, &x);
    if (h != INVALID_HANDLE_VALUE)
    {
        FindClose(h);
        return 1;
    }
    return 0;
}

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

void FindInFilesThread(void)
{
    //   if (QuerySaveAll() == IDCANCEL)
    //      return ;
    if (DialogBox(hInstance, "FINDINFILESDLG", hwndFrame, (DLGPROC) &fifDlgProc)
        )
    {
        char args[256];
        char current[512];
        int i = 0;
		SelectErrorWindow(fifwindow);
        sprintf(args, "-no%s%s%s%s", !casesens ? "i" : "", regexp ? "r" : "x",
				subdirs ? "d" : "", wholewords ? "w" : "");
        if (dir[strlen(dir) - 1] != '\\')
            strcat(dir, "\\");

        if (deffile[0])
        {
            sprintf(current, "grep %s \"%s\" \"%s\"", args, find, deffile);
            Execute("grep.exe", current, dir, fifwindow);
        }
        else
        while (TRUE)
        {
            if (filelists[type][i][0] == 0)
                break;
            if (hasFiles(dir, filelists[type][i]))
            {
                sprintf(current, "grep %s \"%s\" \"%s%s\"", args, find,
                    dir, filelists[type][i]);
                Execute("grep.exe", current, dir, fifwindow);
            }
            i++;
        }
		SendErrorMessage(fifwindow, "Done\r\n");
		SendErrorDone(fifwindow);
    }
}

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

void FindInFiles(void)
{
    DWORD threadhand;
    CloseHandle(CreateThread(0, 0, (LPTHREAD_START_ROUTINE)FindInFilesThread, 0,
        0, &threadhand));
}
