/*
**
** Display.cpp
**
** (c) 1999 Didier Levet
**
** Fonctions d'affichage
**
**
*/

#ifndef  CLIB_EXEC_PROTOS_H
#include <clib/exec_protos.h>
#endif

#ifndef  CLIB_INTUITION_PROTOS_H
#include <clib/intuition_protos.h>
#endif

#ifndef  CLASS_DISPLAY_HPP
#include "Display.hpp"
#endif

#ifndef _FILEINFOS_CLASS_HPP
#include "FileInfosC.hpp"
#endif

#ifndef  _PEGASE_HPP
#include "Pegase.hpp"
#endif

//========== Localisation.

#define CATCOMP_ARRAY
#ifndef  PEGASE_H
#include "Pegase.h"                     // Localisation.
#endif


static const char _CatName[] = "Pegase.catalog";
extern const char *_verstr_;


//----------------------------------------------------------------------------------------------------
//=========================================== Localisation ===========================================
//----------------------------------------------------------------------------------------------------

extern struct Library *LocaleBase;

static LocalStrings local;


/// LocalStrings::LocalStrings()
/****** class LocalStrings/CONSTRUCTOR **************************************
*
*   NAME
*   LocalStrings::LocalStrings -- Constructeur
*
*   SYNOPSIS
*   LocalStrings::LocalStrings()
*
*   LocalStrings::LocalStrings();
*
*   FUNCTION
*   Initialise le catalogue.
*
*   BUGS
*
*****************************************************************************
*
*/


LocalStrings::LocalStrings() : pLocaleBase(NULL), pCatalog(NULL)
{
    if (::LocaleBase)
        if ((pLocaleBase = ::OpenLocale(NULL)) != NULL)
            pCatalog = ::OpenCatalogA(pLocaleBase, (STRPTR) ::_CatName, NULL);
}
///
/// LocalStrings::~LocalStrings()
/****** class LocalStrings/DESTRUCTOR ***************************************
*
*   NAME
*   LocalStrings::~LocalStrings -- Destructeur
*
*   SYNOPSIS
*   LocalStrings::~LocalStrings()
*
*   LocalStrings::~LocalStrings();
*
*   FUNCTION
*   Libère les ressources utilisées par la localisation.
*
*   BUGS
*
*****************************************************************************
*
*/


LocalStrings::~LocalStrings()
{
    if (::LocaleBase)
    {
        if (pCatalog)    ::CloseCatalog(pCatalog);
        if (pLocaleBase) ::CloseLocale(pLocaleBase);
    }
}
///
/// GetString()
/****** Pegase/GetString ****************************************************
*
*   NAME
*   GetString -- Obtenir la traduction d'une chaîne.
*
*   SYNOPSIS
*   string = GetString(iStringID)
*
*   const char * GetString(long);
*
*   FUNCTION
*   Retourne la chaîne localisée associée à l'identificateur passé en
*   paramètre. Si la chaîne localisée n'existe pas, la chaîne originale
*   est renvoyée à la place.
*
*   INPUTS
*   iStringID - Numéro d'identification de la chaîne à retourner.
*
*   RESULT
*   string - Chaîne localisée, ou chaîne originale.
*
*   NOTES
*   Les chaînes originales sont en anglais.
*
*****************************************************************************
*
*/


STRING GetString(long iStringID)
{
    const int NUMSTRINGS = sizeof(CatCompArray)/sizeof(CatCompArray[0]);

    const struct CatCompArrayType *p = CatCompArray;

    for (int i = 0; i<NUMSTRINGS; i++, p++)
    {
        if (p->cca_ID == iStringID)
        {
            return local.read(iStringID, p->cca_Str);
        }
    }
    return "<bad string ID>";
}
///


//----------------------------------------------------------------------------------------------------
//========================================= class CLIDisplay =========================================
//----------------------------------------------------------------------------------------------------

CLIDisplay::CLIDisplay()
{
    char buffer[256];
    BPTR std_out;

    // buffer[0] == 0 && IoErr() == 209 : CON:
    // buffer[0] == 0 && IoErr() == 0   : NIL:
    // name defined   && IoErr() == 0   : FileName

    if ( (std_out = Output()) )
    {
        if ( (NameFromFH(std_out, buffer, 255) != DOSFALSE && buffer[0] != 0) || IoErr() == 0)
            bDisableAnim = TRUE;
    }
}


void Display::PrintErrorMsg(STRING msg)
{
    out() << ::GetString(MSG_ERROR_TXT) << " : " << msg << endl;
}


void Display::PrintDOSError(int errCode)
{
    char buffer[81];
    ::Fault(errCode, NULL, buffer, sizeof(buffer));
    PrintErrorMsg(buffer);
}


void Display::DisplayBanner()
{
    out() << endl << &_verstr_[6] << "\n";
    out() << "© 1998-1999 Didier 'kakace' Levet\n";
    out() << "----------------------------------------\n" << endl;
}


void Display::ShowConfig(const PegaseConfigC& rCfg)
{
    if (rCfg.IsVerbose())
    {
        out() << endl << ::GetString(MSG_DISPSETTINGS_SETUP_TXT) << " :\n";
        out() << ::GetString(MSG_DISPSETTINGS_SOURCE_TXT) << " = ";

        // Afficher chaque fichier à encoder.

        if (rCfg.CurrentIndex())
        {
            ULONG iIndex = 0;

            out() << rCfg[iIndex++] << "\n";
            for (; iIndex < rCfg.CurrentIndex(); ++iIndex)
                out() << " + " << rCfg[iIndex] << "\n";
        }
        else out() << "<" << ::GetString(MSG_NONE_TXT) << ">\n";

        out() << ::GetString(MSG_DISPSETTINGS_DEST_TXT) << " = " << rCfg.GetDestination() << "\n";
        out() << ::GetString(MSG_DISPSETTINGS_PATTERN_TXT) << " = " << rCfg.GetPattern() << endl;

        ShowEncodingInfos(&rCfg);
        out() << endl;
    }
}


void Display::ShowEncodingInfos(const EncoderConfigC *pConfig)
{
    const char *yes = ::GetString(MSG_YES_TXT);
    const char *no  = ::GetString(MSG_NO_TXT);
    STRING s;

    // Afficher les réglages généraux.

    out() << ::GetString(MSG_ENCODING_MODE_TXT) << " ";
    out() << ::GetString(MSG_DISPSETTINGS_LAYER_TXT) << " " << pConfig->GetLayer() + 1 << ", ";
    out() << pConfig->GetBitRate() << " Kbits/s (" << pConfig->GetSampleFreq() << " Hz) ";

    switch (pConfig->GetEncodingMode())
    {
        case STEREO:
            s = ::GetString(MSG_DISPSETTINGS_STEREO_TXT);
            break;
        case MONO:
            s = ::GetString(MSG_DISPSETTINGS_MONO_TXT);
            break;
        case JOINTSTEREO:
            s = ::GetString(MSG_DISPSETTINGS_JOINTSTEREO_TXT);
            break;
    }

    out() << s << endl;

    if (pConfig->IsCopyrighted() | pConfig->IsOriginal() | pConfig->IsCRC())
    {
        out() << ::GetString(MSG_DISPSETTINGS_FLAGS_TXT) << " ";
        if (pConfig->IsCopyrighted()) out() << ::GetString(MSG_DISPSETTINGS_COPYRIGHT_TXT) << " ";
        if (pConfig->IsOriginal())    out() << ::GetString(MSG_DISPSETTINGS_ORIGINAL_TXT) << " ";
        if (pConfig->IsCRC())         out() << ::GetString(MSG_DISPSETTINGS_CRC_TXT) << " ";
        out() << endl;
    }
}


void Display::ShowCurrentJob(const FileInfosC *fi)
{
    u_Time t;

    out() << "\n==================================================\n";
    out() << ::GetString(MSG_ENCODING_TXT) << " " << fi->NodeName() << " [" << fi->GetAudioName() << "]\n";
    out() << ::GetString(MSG_DESTINATION_TXT) << " = " << fi->GetOutputName() << "\n";
    out() << fi->GetNumFrames() << " " << ::GetString(MSG_DISPSETTINGS_SAMPLES_TXT) << ", ";
    out() << ((fi->GetNumChannels() == 2) ? ::GetString(MSG_DISPSETTINGS_STEREO_TXT)
                                         : ::GetString(MSG_DISPSETTINGS_MONO_TXT));
    t = fi->GetTime();
    if (t.iTime == 0x5858)
    {
        out() << " (--:--)" << endl;
    }
    else
    {
        out() << " (" << (short) t.sTime.bMinutes;
        out() << ( (t.sTime.bSecondes < 10) ? ":0" : ":");
        out() << (short) t.sTime.bSecondes << ")" << endl;
    }
}


int Display::UpdateProgression(ULONG val, FileInfosC *fi)
{
    static int frame_cnt = 0;

    if (bDisableAnim == FALSE)
    {
        if (val == 0)
        {
            if (++mDotsDelay > 200)
            {
                mDotsDelay = 0;
                out() << '.';
            }
        }
        else
        {
            for (; mAnimVal <= val; mAnimVal += 2)
            {
                if (mAnimVal % 10)  out() << '.';
                else                out() << mAnimVal << '%';
            }
        }
        out().flush();
    }

    int user_break = 0;

    if (++frame_cnt == CHECK_BREAK_DELAY) {
        if ( (user_break = ::CheckSignal(SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D)) )
        {
            fi->SetIoError(IOERR_INTERNAL, ERROR_BREAK);
        }
        frame_cnt = 0;
    }

    return user_break;
}


WBDisplay::WBDisplay()
{
    char window_specs[128];
    const char *window_name = "CON:0/15/640/220/Pegase/AUTO/CLOSE/WAIT";

    if (!((struct Process *) ::FindTask(NULL))->pr_CLI)
    {
        // Lire la variable d'environnement

        if (::GetVar("PEGASE_WBCONSOLE", window_specs, sizeof(window_specs), GVF_GLOBAL_ONLY) > 0 && ::IoErr() < 128)
        {
            window_name = window_specs;     // Variable trouvée, et non tronquée.
        }

        // Ouvrir la fenêtre de console.

        if ( (ostr = new ofstream) )
            ostr->open(window_name);
    }

    bFromWB = TRUE;
}


WBDisplay::~WBDisplay()
{
    if (ostr)
    {
        ostr->flush();
        delete ostr;
    }
}

