#include "ninox.h"

/*
 * Read a P6 PPM file on standard input, and write a P6 PPM file on standard output.
 * The output file will have the object centered, with the assumption that any
 * pixels with values >= 10% R/G/B are part of the object, and elsewise are background
 */

#define XSTR(foo) STR(foo)
#define STR(foo) #foo

main(int argc, char *argv[])
	{
	FILE *z;
	char fname[1024];
	int i,j;
	int FilesProcessed = 0;
	unsigned int Start,Run;
	
	Start = time(0);
	Srandom();

	Print("\n%s: (C)Copyright 2005-2008 Anthony Wesley, All Rights Reserved\n",XSTR(VERSION));
	Print("This program can be freely distributed. Source code is available\n");
	Print("upon request from http://www.acquerra.com.au/astro/software/\n");

	// If called with no arguments then print all possible switches and exit
	if (argc==1) {
	   _CMD_help();
	   exit(0);
	   }

	for(i=1; i < argc; ++i) {
	   char *arg = argv[i];

	   if (arg[0]=='-') {
		// set VAR=VALUE
		int n = SetVariable(arg+1);
		if (n == 0 ) {
		   Print("%s: Unknown switch\n",arg);
		   exit(1);
		   }
		if (n < 0) {
		   Print("Error in switch %s\n",arg);
		   exit(1);
		   }
		continue;
		}

	   while(strlen(arg)>0 && arg[strlen(arg)-1] == '/' || arg[strlen(arg)-1] == '\\') 
		   arg[strlen(arg)-1] = 0;

	   if (isFile(arg) && ImageCount != 0) {
		/* Must be a file to align */
	 	int filecount = Align(arg);
	 	if (! filecount) {
		   Print("Alignment failed on [%s]\n",arg);
		   exit(1);
		   }
		FilesProcessed += filecount;
		}
	   else if (isDirectory(arg)) {
		FilesProcessed += ProcessDir(arg);
		}
	   else {
		Print("Unknown argument: '%s'\n",arg);
		exit(1);
		}
	   }
	   
	if (InteractiveMode) {
	   Interact();
	   exit(0);
	   }

	// No files specified? Then process the current directory by default
	if (FilesProcessed == 0) {
	   FilesProcessed += ProcessDir(".");
	   }

	if (! FilesProcessed) {
	   Print("Found no files to process.\n");
	   }
	else {
	   Print("\n  -> Processed %d files\n",FilesProcessed);
	   }

        if (StackCount>0 && StackFile != NULL) {
	  if (OutDir && !strstr(StackFile,"\\") && !strstr(StackFile,"/"))
		sprintf(fname,"%s/%s",OutDir,StackFile);
	  else	strcpy(fname,StackFile);
	  Mkdir(OutDir);
          if (!Quiet) Print("  -> Writing stackfile %s from %d frames\n",fname,StackCount);
          write_stack_file(fname);
          }

	if (QEstimator) {
	  //if (OutDir) 	sprintf(fname,"%s/Quality.txt",OutDir);
	  //else 		strcpy(fname,"Quality.txt");
	  strcpy(fname,"Quality.txt");

	   if (QRenumberFiles) {
		Print("\nRenumbering...\n");
		QRenumber(QRenumberFiles);
		}
	   WriteQFile(fname);
	   }

	// Save the commandline
	if (0 && OutDir)sprintf(fname,"%s/ninox.run",OutDir);
	else 		strcpy(fname,"ninox.run");

	for(i=0; fname[i]; ++i) if (fname[i]=='\\') fname[i]='/';

	z = OpenLogfile(fname,"ab");
	if (z != NULL) {
	   for(i=0; i<argc; ++i)
	      if (argv[i][0] == '-')
	      fprintf(z,"%s ",argv[i]);
	   fprintf(z,"\n");
	   fclose(z);
	   }
	else {
	   Print("Cannot save settings file %s\n",fname);
	   }

	if (DetectHotPixels) {
	   WriteHotPixelFile("hotpixels.txt");
	   }

	Run = time(0) - Start;
	printf("running time = %02dm%02ds seconds\n",Run/60,Run%60);
	exit(0);
	}

static int
comp(const void *ptr1, const void *ptr2)
	{
	char **s1 = (char **)ptr1;
	char **s2 = (char **)ptr2;
	char *p1 = *s1;
	char *p2 = *s2;
	int i1,i2;

	// seek to end of string
	p1 += strlen(p1);
	p2 += strlen(p2);

	// seek back until we find the last path entry
	while(p1 != *s1 && *(p1-1) != '/' && *(p1-1) != '\\') --p1;
	while(p2 != *s2 && *(p2-1) != '/' && *(p2-1) != '\\') --p2;
	
	// Go forward until we find a digit
	while(*p1 && ! isdigit(*p1)) ++p1;
	while(*p2 && ! isdigit(*p2)) ++p2;

	// Hopefully we are now on a substring that can be used for comparison
	i1 = atoi(p1);
	i2 = atoi(p2);

	if (i1<i2) return -1;
	if (i1>i2) return 1;
	return 0;
	}

#define DIR_MAX_COUNT 32768

// Look in the named directory for files to process
int ProcessDir(char *dir)
	{
	char fname[256];
	struct dirent *e;
	DIR *d = opendir(dir);
	int i,count=0,prepend_dir,FileCount;
	char *file_list[DIR_MAX_COUNT];

	if (d==NULL) {
	   Print("Error opening directory %s\n",dir);
	   return 0;
	   }

	if (StreamFilter) init_streamfilter();

	// Munch off trailing slash
	i = strlen(dir) - 1; 
	if (dir[i] == '/' || dir[i] == '\\') dir[i] = 0;

	if (dir[0]=='.' && dir[1]==0)
	   prepend_dir = 0;
	else
	   prepend_dir = 1;

	while(e = readdir(d)) {
	   if (strlen(e->d_name)>4) {
		if (prepend_dir) sprintf(fname,"%s/%s",dir,e->d_name);
		else strcpy(fname,e->d_name);

	   	if (! access(fname,R_OK|F_OK) && 
		   (	strstr(fname,".bmp") || strstr(fname,".BMP") ||
			strstr(fname,".fit") || strstr(fname,".FIT") || strstr(fname,".fta")) &&
		    ImageCount != 0) {
		   	file_list[count++] = strdup(fname);
			--ImageCount;
			if ((count%1000)==0) printf("Loaded %d files...\n",count);
			}

		if (count>=DIR_MAX_COUNT) {
		   Print("Max count of %d files reached!\n",DIR_MAX_COUNT);
		   exit(1);
		   }
		}
	   }
	closedir(d);

	qsort(file_list,count,sizeof(char *),comp);

	for(i=FileCount=0; i<count; ++i) {
	   char *fname = file_list[i];
	   int fc = Align(fname);
	   if (! fc) Print("Alignment failed on [%s]\n",fname);
	   FileCount += fc;
	   free(file_list[i]);
	   }

	return FileCount;
	}

