/** 
* @file PascalResults.cpp
* @brief read and write pascal style results
* @author Erik Rodner
* @date 09/09/2008

*/
#include <iostream>

#include "core/basics/StringTools.h"
#include "PascalResults.h"

using namespace OBJREC;

using namespace std;
// refactor-nice.pl: check this substitution
// old: using namespace ice;
using namespace NICE;

void PascalResults::write ( char *templatefn, 
			    // refactor-nice.pl: check this substitution
			    // old: const string & imgfn,
			    const std::string & imgfn,
			    const LocalizationResult & l,
			    const ClassNames & classNames )
{
    for ( LocalizationResult::const_iterator i = l.begin(); i != l.end(); i++ )
    {
	const SingleLocalizationResult *sr = *i;
	const ClassificationResult *r = sr->r;
	int classno = r->classno;
	// refactor-nice.pl: check this substitution
	// old: string classname = classNames.text(classno);
	std::string classname = classNames.text(classno);

	double score = r->scores.get(classno);

	int xi, yi, xa, ya;
	sr->getBoundingBox ( xi, yi, xa, ya );

	char filename[1024];

	sprintf ( filename, templatefn, classname.c_str() );
	ofstream os ( filename, ios_base::app );

	if ( !os.good() ) {
	    fprintf (stderr, "Error writing to filename %s\n", filename );
	    exit(-1);
	}

	// refactor-nice.pl: check this substitution
	// old: string filetag = StringTools::baseName ( imgfn, false );
	std::string filetag = StringTools::baseName ( imgfn, false );

	os << filetag << " "
	   << score << " "
	   << xi << " "
	   << yi << " "
	   << xa << " "
	   << ya << " " << endl;

	os.close();
    }
}

void PascalResults::read ( map<string, LocalizationResult *> & results, 
			   // refactor-nice.pl: check this substitution
			   // old: string filename,
			   std::string filename,
			   int classno, int backgroundClassno, bool calibrate )
{
    ifstream ifs ( filename.c_str(), ios::in );

    if ( ! ifs.good() ) {
	fprintf (stderr, "Unable to read file %s\n", filename.c_str() );
	exit(-1);
    }

    // refactor-nice.pl: check this substitution
    // old: string id;
    std::string id;
    double confidence;
    double xi, yi, xa, ya;
    double minconfidence = numeric_limits<double>::max();
    double maxconfidence = - numeric_limits<double>::max();
    long objects_count = 0;

    vector<SingleLocalizationResult *> slrresults;

    while (!ifs.eof())
    {
	if ( ! (ifs >> id) ) break;
	ifs >> confidence;
	ifs >> xi;
	ifs >> yi;
	ifs >> xa;
	ifs >> ya;

	if ( confidence < minconfidence ) 
	    minconfidence = confidence;
	if ( confidence > maxconfidence )
	    maxconfidence = confidence;

	map<string, LocalizationResult *>::iterator j = results.find(id);
	LocalizationResult *l;
	if ( j == results.end() )
	{
	    l = new LocalizationResult( ); // FIXME
	    results.insert ( pair<string, LocalizationResult *> ( id, l ) );
	} else {
	    l = j->second;
	}

	SparseVector scores;
	scores.insert ( pair<int, double> ( classno, confidence ) );
	scores.insert ( pair<int, double> ( backgroundClassno, 1.0 - confidence ) );
	SingleLocalizationResult *slr = new SingleLocalizationResult ( 
	    new ClassificationResult( classno, scores ), (int)xi, (int)yi, (int)xa, (int)ya );

	if ( calibrate )
	    slrresults.push_back ( slr );

	l->push_back ( slr );

	objects_count++;
    }
    ifs.close();
    fprintf (stderr, "max %f min %f\n", maxconfidence, minconfidence );

    if ( calibrate )
    {
	if ( fabs(maxconfidence-minconfidence) < 1e-10 ) return;
	for ( vector<SingleLocalizationResult *>::iterator i = slrresults.begin();
		    i != slrresults.end(); i++ )
	{
	    SingleLocalizationResult *slr = *i;
	    FullVector & scores = slr->r->scores;
	    double s = scores.get ( classno );
	    s =  (s-minconfidence)/(maxconfidence-minconfidence);
	    s = 0.1 + 0.9*s;
	    scores.reinit ( (backgroundClassno > classno) ? backgroundClassno + 1 : classno + 1 );	
	    scores[classno] = s;
	    scores[classno] = 1.0 - s;
	}
    }

    fprintf (stderr, "PascalResults::read(%s) objects count %ld\n", filename.c_str(), objects_count );
}

