unsigned int optimize(PanoramaData& pano,
                      const char * userScript)
{
    char * script = 0;
    unsigned int retval = 0;

    if (userScript == 0) {
        std::ostringstream scriptbuf;
        UIntSet allImg;
        fill_set(allImg,0, unsigned(pano.getNrOfImages()-1));
        pano.printPanoramaScript(scriptbuf, pano.getOptimizeVector(), pano.getOptions(), allImg, true);
        script = strdup(scriptbuf.str().c_str());
    } else {
        script = const_cast<char *>(userScript);
    }

    OptInfo		opt;
	AlignInfo	ainf;

    if (ParseScript( script, &ainf ) == 0)
	{
		if( CheckParams( &ainf ) == 0 )
		{
			ainf.fcn	= fcnPano;
			
			SetGlobalPtr( &ainf ); 
			
			opt.numVars 		= ainf.numParam;
			opt.numData 		= ainf.numPts;
			opt.SetVarsToX		= SetLMParams;
			opt.SetXToVars		= SetAlignParams;
			opt.fcn			= ainf.fcn;
			*opt.message		= 0;

			RunLMOptimizer( &opt );
			ainf.data		= opt.message;
            // get results from align info.
#ifdef DEBUG_WRITE_OPTIM_OUTPUT
            fullPath path;
            StringtoFullPath(&path, DEBUG_WRITE_OPTIM_OUTPUT_FILE );

		    ainf.data		= opt.message;
            WriteResults( script, &path, &ainf, distSquared, 0);
#endif
            pano.updateVariables( GetAlignInfoVariables(ainf) );
            pano.updateCtrlPointErrors( GetAlignInfoCtrlPoints(ainf) );
		} else {
            std::cerr << "Bad params" << std::endl;
            retval = 2;
        }
		DisposeAlignInfo( &ainf );
    } else {
        std::cerr << "Bad params" << std::endl;
        retval = 1;
    }
    if (! userScript) {
        free(script);
    }
    return retval;
}
int main(int argc,char *argv[])
{
	aPrefs		aP;

	char*		script;
	OptInfo		opt;
	AlignInfo	ainf;

	fullPath	infile;
	//fullPath	outfile;

	//	

	SetAdjustDefaults(&aP);

	if(argc != 2)
	{
		printf(PT_OPTIMIZER_VERSION);
		printf("Usage: %s /path/to/script.txt\n", argv[0]);
		exit(1);
	}

	StringtoFullPath(&infile, argv[1]);

	script = LoadScript( &infile );
	if( script != NULL )
	{
		if (ParseScript( script, &ainf ) == 0)
		{
			if( CheckParams( &ainf ) == 0 )
			{
				ainf.fcn	= fcnPano;
				
				SetGlobalPtr( &ainf ); 
				
				opt.numVars 		= ainf.numParam;
				opt.numData 		= ainf.numPts;
				opt.SetVarsToX		= SetLMParams;
				opt.SetXToVars		= SetAlignParams;
				opt.fcn			= ainf.fcn;
				*opt.message		= 0;

				RunLMOptimizer( &opt );
				ainf.data		= opt.message;
				WriteResults( script, &infile, &ainf, distSquared, 0);
				exit(0);
			}
      //TODO: if optCreatePano is 1 then should call stitcher  OR  the option removed
      //if (ainf.sP.optCreatePano == 1)
      //{
      //   Stitch();
      //}
			DisposeAlignInfo( &ainf );
		}
		free( script );
	}
	exit(1);
}
static int panoMenderImageFileNamesReadFromScript(fullPath **ptrImageFileNames, fullPath *scriptFileName)
{
    char *script;
    AlignInfo alignInfo;
    int counter;
    int i;

    // We don't have any images yet. We read the Script and load them from it.
    if (ptDebug) {
	fprintf(stderr, "Loading script [%s]\n", scriptFileName->name);
    }
	
    script = LoadScript(scriptFileName);
    
    if (script == NULL) {
	PrintError("Could not load script [%s]", scriptFileName->name);
	return -1;
    }
    
    // parse input script and set up an array of input file names
    if (ParseScript(script, &alignInfo) != 0) {
	// print error
	
	PrintError("Panorama script parsing error");
	return 0;
    }
    
    // The parser of panotools is really broken. To retrieve each
    // input filename it reads the file,
    // finds the first filename, then removes it, and writes the rest of the file again
    // This is done recursively 
    
    counter = alignInfo.numIm;
    
    if (counter != 0) {
	
	// Try to find filenames in input section
	if (ptDebug) {
	    fprintf(stderr, "Found %d images in script file in INPUT section\n", counter);
	}
	// Allocate their space
	if ((*ptrImageFileNames = malloc(512 * counter)) == NULL) {
	    PrintError("Not enough memory");
	    exit(1);
	}
	
	//Iterate over input images and populate input filename array
	for (i = 0; i < counter; i ++) {
	    //If the image filenames don't appear to have any path information, then 
	    //prepend the path to the script (if any) that was specified on the 
	    //command line (Note: this was the only behavior in the original 
	    //PTStitcher.  It has been moved into this conditional block because
	    //the script path could get prepended to an already fully qualified
	    //filename...not very useful.
	    if (ptDebug) {
		fprintf(stderr, "Processing image [%s] from 'i' line %d\n", alignInfo.im[i].name, i);
	    }

	    panoMenderSetFileName(&((*ptrImageFileNames)[i]), alignInfo.im[i].name, scriptFileName);
	    
	    if (ptDebug) {
		fprintf(stderr, "Reading image filename [%s] from 'i' line %d\n", (*ptrImageFileNames)[i].name, i);
	    }
	    
	    
	}
	DisposeAlignInfo(&alignInfo);
    }	
    if (counter == 0) {
	// Sometimes the names of the images are not in the 'o' line, then assume they are
	// in the 'i' line.
	
	
	// create a temporary copy we can overwrite
	fullPath scriptPathName;
	
	counter = numLines(script, 'o');
	
	if (counter == 0) {
	    PrintError("No images found input file script file (there are no 'o' lines nor 'i' lines");
	    exit(1);
	}
	// Allocate their space
	if ((*ptrImageFileNames = malloc(512 * counter)) == NULL) {
	    PrintError("Not enough memory");
	    exit(1);
	}
	
	
	panoMenderDuplicateScriptFile(scriptFileName->name, script, &scriptPathName);
	
	for (i = 0; i < counter; i++) {
	    aPrefs* preferences;
	    if ( (preferences = readAdjustLine(&scriptPathName)) == NULL) {
		PrintError("No 'i' line for image number %d", i);
		exit(1);
	    }
	    
	    if (ptDebug) {
		fprintf(stderr, "Processing image [%s] from 'o' line %d\n", preferences->im.name, i);
	    }

	    panoMenderSetFileName(&((*ptrImageFileNames)[i]), preferences->im.name, scriptFileName);
	    
	    if (ptDebug) {
		fprintf(stderr, "Reading image filename [%s] from 'i' line %d\n",
			(*ptrImageFileNames)[i].name, i);
	    }
	    if (preferences->td != NULL)
		free(preferences->td);
	    
	    if (preferences->ts != NULL)
		free(preferences->ts);
	    
	    free(preferences);
	    
	} // end of for (i = 0; i < counter; i++) {
	free(script); 
	
	remove(scriptPathName.name);
	
    }
    return counter;
}