/* ======================================================================== *\
!
! *
! * This file is part of MARS, the MAGIC Analysis and Reconstruction
! * Software. It is distributed to you in the hope that it can be a useful
! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
! * It is distributed WITHOUT ANY WARRANTY.
! *
! * Permission to use, copy, modify and distribute this software and its
! * documentation for any purpose is hereby granted without fee,
! * provided that the above copyright notice appear in all copies and
! * that both that copyright notice and this permission notice appear
! * in supporting documentation. It is provided "as is" without express
! * or implied warranty.
! *
!
!
!   Author(s): Thomas Bretz  06/2001 <mailto:tbretz@uni-sw.gwdg.de>
!
!   Copyright: MAGIC Software Development, 2000-2002
!
!
\* ======================================================================== */

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
// MWriteAsciiFile                                                         //
//                                                                         //
// If you want to store a single container into an Ascii file you have     //
// to use this class. You must know the name of the file you wanne write   //
// (you should know it) and the name of the container you want to write.   //
// This can be the name of the class or a given name, which identifies     //
// the container in a parameter container list (MParList).                 //
// The container is written to the ascii file if its ReadyToSave flag is   //
// set (MParContainer)                                                     //
//                                                                         //
// You can write more than one container in one line of the file, see      //
// AddContainer.                                                           //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////

#include "MWriteAsciiFile.h"

#include <fstream.h>

#include "MLog.h"
#include "MLogManip.h"

#include "MParList.h"

ClassImp(MWriteAsciiFile);

// --------------------------------------------------------------------------
//
// Init. Replaces the same code used in all constructors.
//
void MWriteAsciiFile::Init(const char *filename, const char *name, const char *title)
{
    fName  = name  ? name  : "MWriteAsciiFile";
    fTitle = title ? title : "Task to write one container to an ascii file";

    fNameFile = filename;

    fOut = new ofstream(fNameFile);
}

// --------------------------------------------------------------------------
//
// Specify the name of the ascii output file 'filename' and the name
// of the container you want to write. (Normally this is the name
// of the class (eg. MHillas) but it can also be a different name which
// identifies the container in the parameter list.
// Because you cannot write more than one container there is no Add-function
// like in MWriteRootFile.
//
//  For Example: MWriteAsciiFile("file.txt", "MHillas");
//
MWriteAsciiFile::MWriteAsciiFile(const char *filename, const char *contname,
                                 const char *name, const char *title)
{
    Init(filename, name, title);

    AddContainer(contname);
}

// --------------------------------------------------------------------------
//
// Specify a the name of the ascii output file 'filename' and a pointer to
// the container you want to write. 
// Because you cannot write more than one container there is no Add-function
// like in MWriteRootFile.
//
//  For Example: MHillas hillas;
//               MWriteAsciiFile("file.txt", &hillas);
//
//
MWriteAsciiFile::MWriteAsciiFile(const char *filename, MParContainer *cont,
                                 const char *name, const char *title)
{
    Init(filename, name, title);

    AddContainer(cont);
}

// --------------------------------------------------------------------------
//
// Destructor. Delete the output file if necessary (it is closed
// automatically by its destructor.
//
MWriteAsciiFile::~MWriteAsciiFile()
{
    fContNames.SetOwner();

    delete fOut;
}

// --------------------------------------------------------------------------
//
// Check if the containers are ready for writing. If so write them.
// The containers are written in one line, one after each other.
// If not all containers are written (because of the IsReadyToSave-flag)
// a warning message is print.
//
void MWriteAsciiFile::CheckAndWrite() const
{
    Bool_t written = kFALSE;

    MParContainer *cont = NULL;

    Int_t num = fContainer.GetEntries();

    TIter Next(&fContainer);

    while ((cont=(MParContainer*)Next()))
    {
        if (!cont->IsReadyToSave())
            continue;

        cont->AsciiWrite(*fOut);
        *fOut << " ";
        written = kTRUE;

        num--;
    }

    if (written)
        *fOut << endl;

    if (num!=0)
      *fLog << warn << "Warning - given number of containers doesn't fit number of written containers." << endl;
}

// --------------------------------------------------------------------------
//
// Return open state of the file
//
Bool_t MWriteAsciiFile::IsFileOpen() const
{
    return (bool)(*fOut);
}

// --------------------------------------------------------------------------
//
// Tries to get all containers from the ParList which were given by name
// adds them to the list of pointers to the container which should be
// written to the ascii file.
//
Bool_t MWriteAsciiFile::GetContainer(MParList *pList)
{
    TObject *obj = NULL;

    TIter Next(&fContNames);

    while ((obj=Next()))
    {
        const char *name = obj->GetName();

        MParContainer *cont = (MParContainer*)pList->FindObject(name, "MParContainer");
        if (!cont)
        {
            *fLog << err << dbginf << "Cannot find parameter container '" << name << "'." << endl;
            return kFALSE;
        }

        AddContainer(cont);
    }

    return kTRUE;
}

// --------------------------------------------------------------------------
//
// Add another container (by name) to be written to the ascii file.
// The container will be output one after each other in one line.
//
void MWriteAsciiFile::AddContainer(const char *cname)
{
    TNamed *named = new TNamed(cname, "");
    fContNames.AddLast(named);
}

// --------------------------------------------------------------------------
//
// Add another container (by pointer) to be written to the ascii file.
// The container will be output one after each other in one line.
//
void MWriteAsciiFile::AddContainer(MParContainer *cont)
{
    fContainer.AddLast(cont);
}

