/*
**
** 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)))
            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]) || !IoErr())
            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-2000 Didier 'kakace' Levet\n" << endl;
}


void Display::ShowConfig(const PegaseConfigC& rCfg)
{
    static const int CDDA_bo[] = {MSG_CDDA_AUTODETECT_TXT, MSG_CDDA_INTEL_TXT, MSG_CDDA_MOTOROLA_TXT};
    const char *eq = " = ";

    if (rCfg.IsVerbose()) {
        out() << endl << ::GetString(MSG_DISPSETTINGS_SETUP_TXT) << " :\n";
        out() << ::GetString(MSG_DISPSETTINGS_SOURCE_TXT) << eq;

        // 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) << eq << rCfg.GetDestination() << '\n';
        out() << ::GetString(MSG_DISPSETTINGS_PATTERN_TXT) << eq << rCfg.GetPattern() << endl;
        out() << ::GetString(MSG_CDDA_BYTEORDER_TXT) << eq << ::GetString(CDDA_bo[rCfg.GetCDDAFmt()]) << endl;
        if (rCfg.DeleteSource())
            out() << ::GetString(MSG_DELETE_SRC_TXT) << 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";
    out() << ::GetString(MSG_ENCODING_TXT) << " \"" << fi->NodeName() << "\" [" << fi->GetAudioName() << "] ";
    out() << ::GetString(MSG_TO_TXT) << " \"" << fi->GetOutputName() << "\"\n";
    out() << fi->GetNumFrames() << ' ' << ::GetString(MSG_DISPSETTINGS_SAMPLES_TXT) << ", " << fi->GetSampleFreq() << " Hz ";
    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) {
        if (!val) {
            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;
    }
}

