// (c) 1991-2007 Electronic Arts Inc.

const char *SPIT_history[] =
{
"------------------------------------------------------------------",
"                                                                  ",
"                           Zin v1.00                              ",
"                                                                  ",
"                    by FrANK G. Barchard, EAC                     ",
"                                                                  ",
"                   Main program - May 05, 2003                    ",
"                                                                  ",
"------------------------------------------------------------------",
"                                                                  ",
" Version Date   SE History:                                       ",
" ------- ----   -- --------                                       ",
"    1.00 030507 FB based on whereis. zin gets system info	       ",
"                                                                  ",
"------------------------------------------------------------------",
"\0"
};


/****************************************************************/
/*  Spit Setup                                                  */
/****************************************************************/

#if defined(_MSC_VER)
#pragma warning(push,1)
#include <windows.h>
#pragma warning(pop)
#endif

#include "spit.h"
#if defined(_MSC_VER)
#include "gclip.h"
#endif

const char TextVersion[]="1.23 (Samba) 2007.12.4";
#define TOOL_VERSION 123
#define TOOL_NAME "zin"

/****************************************************************/
/*  Internal Functions                                          */
/****************************************************************/

#define MAXREGLEN 256
#define MSGLEN    1024

char OPTfilename[MAXREGLEN+4]="";
char OPTwidth[MAXREGLEN+4]="";
char OPTheight[MAXREGLEN+4]="";
char OPTbpp[MAXREGLEN+4]="";
int OPTclip;
int OPTdir;
int OPTquote;
int OPTshortname;
int OPTlongname;

static void unquote(char *d,const char *s)
{
    while (*s)
    {
        if (*s!='"')
            *d = *s;
        ++s;
        ++d;
    }
    *d = 0;
}

static void CLPtext(const char *str)
{
#if defined(_MSC_VER)
    GCLIP *gclip = GCLIP_wopen();
    HGLOBAL hData;

    if (gclip)
    {
        hData = GlobalAlloc(GHND | GMEM_SHARE, strlen(str)+1);  /* note freed by clipboard itself */
        if (hData)
        {
            char *p = (char *) GlobalLock(hData);
            if (p)
            {
                strcpy(p, str);
                GCLIP_write(gclip, CF_TEXT, p, strlen(p)+1);
            }
        }
        GCLIP_wclose(gclip);
    }
#endif
}


char *WHERE_getpath( char *newmatch,const char *old)
{
    char *d;
    char *x = NULL;

    strcpy(newmatch, old);

    d = newmatch;
    while (*d)                                  /* find last ':','/','\' */
    {
        if (*d==(char)':' || *d==(char)'/' || *d==(char)'\\')
            x = d;
        ++d;
    }

    if (x)                                     /* remove filename */
    {
        if (*x==':')
            ++x;
        *x = '\0';
    }
    else
    {
        *newmatch = '\0';
    }

    return(newmatch);
}

static void WHERE_report(const char *zin)
{
    char wherebuf[512];

    strcpy(wherebuf,zin);

    for (int i=0; i<OPTdir; ++i)
        WHERE_getpath(wherebuf,wherebuf);

    if (OPTquote==1 || (OPTquote==-1 && !OPTdir && wherebuf[0]!='"' && strchr(wherebuf,' ')))
    {
        char tempbuf[512];
        strcpy(tempbuf,wherebuf);
        sprintf(wherebuf,"\"%s\"",tempbuf);
    }

    if (OPTshortname)
    {
        char shortbuf[512];
        GetShortPathName(wherebuf,shortbuf,sizeof(shortbuf));
        strcpy(wherebuf,shortbuf);
    }
    if (OPTlongname)
    {
        char longbuf[512];
        GetLongPathName(wherebuf,longbuf,sizeof(longbuf));
        strcpy(wherebuf,longbuf);
    }
    if (OPTverbose)
        printf("%s\n",wherebuf);
    if (OPTclip)
        CLPtext(wherebuf);
}


bool Zin_file(const char *filename)
{
    printf("file info: %s\n",filename);

    char fullbuf[512];
    char *justthefile;
    GetFullPathName(filename,sizeof(fullbuf),fullbuf,&justthefile);
    printf("full name: %s\n",fullbuf);
    printf("file name: %s\n",justthefile);

    char longbuf[512];
    GetLongPathName(fullbuf,longbuf,sizeof(longbuf));
    printf("long name: %s\n",longbuf);

    char shortbuf[512];
    GetShortPathName(fullbuf,shortbuf,sizeof(shortbuf));
    printf("short name: %s\n",shortbuf);

    char uni[512];
    DWORD sizeof_uni = sizeof(uni);

    DWORD errorcode = WNetGetUniversalName(fullbuf,UNIVERSAL_NAME_INFO_LEVEL,(void *)uni,&sizeof_uni);
    char *msg=0;
    switch (errorcode)
    {
        case ERROR_BAD_DEVICE        : msg = "ERROR_BAD_DEVICE"; break;
        case ERROR_CONNECTION_UNAVAIL: msg = "ERROR_CONNECTION_UNAVAIL"; break;
        case ERROR_EXTENDED_ERROR    : msg = "ERROR_EXTENDED_ERROR"; break;
        case ERROR_MORE_DATA         : msg = "ERROR_MORE_DATA"; break;
        case ERROR_NOT_SUPPORTED     : msg = "ERROR_NOT_SUPPORTED"; break;
        case ERROR_NO_NET_OR_BAD_PATH: msg = "ERROR_NO_NET_OR_BAD_PATH"; break;
        case ERROR_NO_NETWORK        : msg = "ERROR_NO_NETWORK"; break;
        case ERROR_NOT_CONNECTED     : msg = "ERROR_NOT_CONNECTED"; break;
        default: break;
    }

    if (!errorcode)
        printf("unc name: %s\n",((UNIVERSAL_NAME_INFO *) uni)->lpUniversalName);
    else
        printf("unc error: %x %s",errorcode,msg);

    return false;
}

bool Zin_system(void)
{
    printf("system info\n");
    return true;
}




/*
;
; ABSTRACT
;
; zin - finds files in your paths
;
; SUMMARY
;
; zin -options [files]
;     @file     response file, containing a list of options and files
;     -nologo   disable banner
;     -v0       no console output
;     -v1       prints source file name and errors
;     -v2       status line for each file (default)
;     -v3       additional info
;
; DESCRIPTION
;
; Zin finds files on your system.
; It will find any file type, but the intent is executables/dlls and headers.
; executables/dlls, headers and libraries for all
;
; Zin searches through various methods, in the following order
;
;   current folder
;   PATH         pc executables search path
;
;   System Registry
;
;   LIB          visual c include path
;   INCLUDE      visual c library path
;   PS2_CPATH    ps2 c include path
;   /usr/local/sce/ee/lib ps2 library path
;   MWCIINCLUDE  metrowerks include path
;   MWLIBRARIES  metrowerks library path
;
;   plugin folders of
;   P2
;   ACDsee
;   Photoshop
;
;   THRASH_DRIVERNAME
;
; RETURNS
;
; clipboard contains name of full path where the file was found
; no return code
;
; SEE ALSO
;
; huff, Spit
;
; SAMPLE OUTPUT
;
; >zin dolphin.h
; C:\DolphinSDK1.0\include\dolphin.h
;
; END ABSTRACT
;
*/

char *optionhelp[]=
{
    "    @file      response file, containing a list of options and files\n",
    "    -nologo    disable banner\n",
    "    -v0        no console output\n",
    "    -v1        prints source file name and errors\n",
    "    -v2        status line for each file (default)\n",
    "    -v3        additional info\n",
    "    -clip      put result in clipboard (default)\n",
    "    -d         return directory\n",
    "    -d<n>      strip N directory levels from path\n",
    "    -q-1       quote names that have spaces\n",
    "    -q0        don't quote names (default)\n",
    "    -q         quote names\n",
    "    -noclip    dont put result in clipboard\n",
    "    -shortname reduce long names to 8.3 DOS short names\n",
    "    -longname  expand to long path names\n",
    "    -time      show execution time\n",
    0,
};

/****************************************************************/
/*  SPIT Routines                                               */
/****************************************************************/

void SPIT_reset(void)
{
    OPTbanner = 0;
    OPTminargs = 0;
    OPTwrite = 0;
    OPTclip = 1;
    OPTdir = 0;
    OPTquote = 0;
    OPTshortname = 0;
    OPTlongname = 0;
    OPTtime = 0;
    return;
}

void SPIT_usage(const char *prgname, const char *envname, const char *urlname, int utype)
{
    char **hlp;

    printf("ZIN v%s by FrANK G. Barchard\n",TextVersion);

    if (utype)
        printf("USAGE: %s -options [files]\n", prgname);

    switch (utype)
    {
        case 0:
        case 1:
            break;

        case 2:
            puts("    -v verbose               -clip   put results in clipboard");
            puts("    -d return directory");
            puts("     @ response file         -noclip disable clipboard result");
          printf("type '%s -h' for more help\n", prgname);
          printf("type '%s -help' for web page (%s)\n", prgname, urlname);
            break;

        case 3:
          printf("VERSION: %s v%s, Spit v%.2f\n",SPIT_MACHINE,TextVersion,(float)SPIT_VERSION/100.0f);
            puts("SUMMARY: Finds files on your system");
          printf("         SPIT environment variable is %s\n",envname);
            puts("");

            hlp = optionhelp;
            while (*hlp)
            {
                printf("%s",*hlp);
                ++hlp;
            }
            break;

         case 4:
            puts("");
            {
                hlp = optionhelp;
                while (*hlp)
                {
                    if (SPIT_strstr(*hlp,envname))
                        printf("%s",*hlp);
                    ++hlp;
                }
                puts("");
            }
            break;

        default:
            break;
    }
}

char *SPIT_opt(const char* optptr)
{
    char *d=NULL;
    switch (*optptr|(char)' ')
    {
        case 'c':
            if (!strnicmp(optptr,"clip",4))
            {
                OPTclip = !OPTclip;
                d = SPIT_getopt( &OPTclip,optptr+4, "clipboard", 0, 1);
                OPTclip = !OPTclip;
            }
            break;

        case 'd':
            d = SPIT_getopt( &OPTdir,optptr+1, "directory level", 0, 32);
            break;

        case 'l':
            if (!strnicmp(optptr,"longname",8))
            {
                d = SPIT_getopt( &OPTlongname,optptr+8, "long filenames", 0, 1);
            }
            break;

        case 'n':
            if (!strnicmp(optptr,"noclip",6))
            {
                OPTclip = !OPTclip;
                d = SPIT_getopt( &OPTclip,optptr+6, "disable clipboard", 0, 1);
                OPTclip = !OPTclip;
            }
            break;

        case 's':
            if (!strnicmp(optptr,"shortname",9))
            {
                d = SPIT_getopt( &OPTshortname,optptr+9, "short filenames", 0, 1);
            }
            break;

        case 't':
            if (!strnicmp(optptr,"time",4))
            {
                d = SPIT_getopt( &OPTtime,optptr+4, "enable timing diagnostics", 0, 1);
            }
            break;

        case 'q':
            d = SPIT_getopt( &OPTquote,optptr+1, "quote names", -1, 1);
            break;


        default:
            break;
    }
    return(d);
}


int main(int argc, char* argv[])
{
    int more;
    int i;
    int rc=0; // return code is number of files not found (0=success)

    double totaltime = SPIT_gettime();
    SPIT_init(SPIT_reset, SPIT_usage, SPIT_opt, SPIT_history);
    do
    {
        more = SPIT_parse(argc, argv, TOOL_NAME, TOOL_VERSION);

        if (!SPIThelpgiven)
        {
            if (SPITargnum)
            {
                for (i=0; i<SPITargnum; ++i)
                {
                    bool ok = Zin_file(SPITdargv[i]);

                    if (!ok)
                         ++rc;
                }
            }
            else
            {
                bool ok = Zin_system();
                if (!ok)
                    ++rc;
            }
        }
    } while (more>0);

    SPIT_restore();

    totaltime = SPIT_gettime()-totaltime;

    if (OPTtime)
    {
        if (totaltime>=60000.0)
            printf("TIME " TOOL_NAME " totaltime %.2f ms (%.2f seconds) (%.2f minutes)\n",totaltime,totaltime/1000.0,totaltime/60000.0);
        else if (totaltime>=1000.0)
            printf("TIME " TOOL_NAME " totaltime %.2f ms (%.2f seconds)\n",totaltime,totaltime/1000.0);
        else
            printf("TIME " TOOL_NAME " totaltime %.2f ms\n",totaltime);
    }

    return(rc);
}
