/* 
   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

**********************************************************************

MAKEGEN.C holds the code for translating IDE project files into
command line make files for use with IMAKE.

**********************************************************************

*/
#include <windows.h>
#include <commctrl.h>
#include <commdlg.h>
#include <richedit.h>
#include <stdio.h>

#include "header.h"

extern char szProjectName[] ;
extern char szInstallPath[] ;

static void putname(FILE *out, char *name)
{
      char buf[256] ;
      int i = 0 ;
      strcpy(buf,relpath(name)) ;

      while (buf[i]) {
         buf[i] = tolower(buf[i]) ;
         i++;
      }
      buf[i] = 0 ;
      fprintf(out,"%s ",buf) ;
}
static void getmacname(char *buf, char *name)
{
   char *p=buf ;
   int i;
   strcpy(buf,name) ;

   while (*p) {
      *p = toupper(*p) ;
      if (*p == '.')
         *p = '_' ;
      p++ ;
   }
   return ;

}
static void put_explicit(FILE *out, FILELIST *list)
{
   DEPENDSLIST *n = list->depends ;
   putname(out,list->output) ;
   fprintf(out,": ") ;
   while (n) {
      putname(out,n->name) ;
      n = n->next ;
   }
   fputc('\n',out) ;
}
static void put_buildfile(FILE *out, PROJLIST *l, FILELIST *list)
{
   char dirty[256],ext[100],buf[256],*p ;
   put_explicit(out,list) ;
   _splitpath(list->name,dirty,dirty,dirty,ext) ;
   getmacname(dirty,l->title) ;
   strcpy(buf,relpath(list->name)) ;
   if (!xstricmpz(ext,".c") || !xstricmpz(ext,".cpp")) {
      fprintf(out,"\t$(CC) $(CFLAGS_%s) $(INCLUDE_%s) %s\n",dirty,dirty,buf) ;
      p = strrchr(buf,'.') ;
      if (!p)
         p = buf  + strlen(buf) ;
      strcpy(p,".asm") ;
      if (l->buildFlags & BF_COMPILEVIAASM)
         fprintf(out,"\t$(ASM) $(AFLAGS_%s) %s\n",dirty,buf) ;
      fprintf(out,"\n") ;
   } else if (!xstricmpz(ext,".asm"))
      fprintf(out,"\t$(ASM) $(AFLAGS_%s) %s\n\n",dirty,buf) ;
	else if (!xstricmpz(ext,".rc"))
      fprintf(out,"\t$(RC) $(RCFLAGS_%s) $(INCLUDE_%s) %s\n\n",dirty,dirty,buf) ;
}
static void put_libFile(FILE *out, PROJLIST *l)
{
   char buf[256] ;
   getmacname(buf,l->title) ;
   fprintf(out,"\n\tdel %s\n",relpath(l->name)) ;
   fprintf(out,"\t$(LIB) $(LIBFLAGS_%s) %s @&&|\n",buf, relpath(l->name)) ;
   fprintf(out,"+ $(%s)\n|\n\n",buf) ;
}
static void put_linkFile(FILE *out, PROJLIST *l)
{
   char dirty[256],buf[256],*p ;
   FILELIST *f = l->files ;
   while (f) {
      p = strrchr(f->output,'.') ;
      if (p && !xstricmp(p,".res"))
         putname(out,f->output) ;
      f = f->next ;
   }
   getmacname(dirty,l->title) ;
   fprintf(out,"\n\t$(LINK) $(LFLAGS_%s) @&&|\n",dirty) ;
   fprintf(out,"$(START_%s) $(%s),",dirty,dirty) ;
   strcpy(buf,relpath(l->name)) ;
   fprintf(out,"%s,",buf) ;
   p = strrchr(buf,'.') ;
   if (p) *p = 0 ;
   fprintf(out,"%s,",buf) ;
   fprintf(out,"$(LIBS_%s),",dirty) ;
   f = l->files ;
   while (f) {
      p = strrchr(f->output,'.') ;
      if (p && !xstricmp(p,".res"))
         putname(out,f->output) ;
      f = f->next ;
   }
   fprintf(out,",,\n|\n\n") ;
}
static void put_defines(FILE *out, PROJLIST *l)
{
   FILELIST *m = l->files ;
   char buf[256],libs[512],startupfile[256],*p ;
   getmacname(buf,l->title) ;
   switch(l->buildType) {
		case BT_CONSOLE:
      default:
         sprintf(libs,"\"%s\\lib\\clwin.lib\" \"%s\\lib\\climp.lib\" ", szInstallPath,szInstallPath) ;
         sprintf(startupfile,"\"%s\\lib\\c0xwin.obj\" ",szInstallPath) ;
         p = "/PE /CON" ;
			break ;
		case BT_WINDOWS:
         sprintf(libs,"\"%s\\lib\\clwin.lib\" \"%s\\lib\\climp.lib\" ", szInstallPath,szInstallPath) ;
         sprintf(startupfile,"\"%s\\lib\\c0win.obj\" ",szInstallPath) ;
         p = "/PE /WIN" ;
			break ;
		case BT_DLL:
         sprintf(libs,"\"%s\\lib\\clwin.lib\" \"%s\\lib\\climp.lib\" ", szInstallPath,szInstallPath) ;
         sprintf(startupfile,"\"%s\\lib\\c0dwin.obj\" ",szInstallPath) ;
         p = "/PE /BDL" ;
			break ;
		case BT_DOS:
         sprintf(libs,"\"%s\\lib\\cldos.lib\" ", szInstallPath) ;
         sprintf(startupfile,"\"%s\\lib\\c0dos.obj\" ",szInstallPath) ;
         p = "" ;
			break ;
	}

   fprintf(out,"#\n# Options\n#\n\n") ;
   fprintf(out,"CFLAGS_%s = %s %s %s\n", buf,
      l->compileopts,
      (l->buildFlags & BF_COMPILEVIAASM) ? "/C+N " : "/c",
      (l->buildFlags & BF_DEBUGINFO) ? "+v" : "") ;
   fprintf(out,"AFLAGS_%s = -fobj\n", buf) ;
   fprintf(out,"RCFLAGS_%s = -r\n", buf) ;
   fprintf(out,"LFLAGS_%s = %s /32 /nci %s %s %s\n",buf,
      l->linkopts, p,  
      (l->buildFlags & BF_MAPFILE) ? "/MP" : "",
      (l->buildFlags & BF_DEBUGINFO) ? "/DEB" : "") ;
   fprintf(out,"LIBFLAGS_%s = %s\n\n",buf,l->libopts) ;
   if (l->includePath[0])
      fprintf(out,"INCLUDE_%s = %s\n",buf,relincludepath(l->includePath)) ;
   else
      fprintf(out,"INCLUDE_%s = \n",buf) ;
   fprintf(out,"LIBS_%s = %s\n",buf, libs) ;
   fprintf(out,"START_%s = %s\n",buf,startupfile) ;

   fprintf(out,"#\n# Rules\n#\n\n") ;

   fprintf(out,"%s = ",buf) ;
   while (m) {
     p = strrchr(m->output,'.') ;
     if (p && !xstricmp(p,".obj")) {
         fprintf(out," \\\n\t") ;
         putname(out,m->output) ;
     }
     m = m->next ;
   }
   fprintf(out,"\n\n") ;
}
static void put_target(FILE *out,PROJLIST *l)
{
   FILELIST *m = l->files ;
   char buf[256] ;
   fprintf(out,"#\n# Build rules for target %s\n#\n",l->title) ;
   put_defines(out,l) ;
   putname(out,l->name) ;
   getmacname(buf,l->title);
   fprintf(out,": $(%s) ",buf) ;
   if (l->buildType == BT_LIBRARY)
      put_libFile(out,l) ;
   else {
      put_linkFile(out,l) ;

      while (m) {
         put_buildfile(out,l,m) ;
         m = m->next ;
      }
   }
}
static void putall(FILE *out, PROJLIST *l)
{
   fprintf(out,"all: ") ;
   while (l) {
      putname(out,l->name) ;
      l = l->next ;
   }
   fprintf(out,"\n\n") ;
}
void genMakeFile(PROJLIST *l, char *filename)
{
   FILE *out = fopen(filename,"w") ;
   if (!out) {
      ExtendedMessageBox("Error in makefile gen",0,"Could not open generated make file for write") ;
      return ;
   }
   CalcRebuilds() ; // to set up the output paths if they aren't 
   fprintf(out,"#\n#  Generated make file for project %s\n#\n",szProjectName) ;
   putall(out,l) ;
   fprintf(out,"#\n# Tools Definitions\n#\n") ;
   fprintf(out,"\nCC=CC386\nLINK=VALX\nASM=NASM\nRC=XRC\nLIB=XLIB\n") ;
   while (l) {
      put_target(out,l) ;
      l = l->next ;
   }
   fclose(out) ;
}