// This may look like C code, but it is really -*- C++ -*-

//<copyright>
// 
// Copyright (c) 1994,95
// Institute for Information Processing and Computer Supported New Media (IICM),
// Graz University of Technology, Austria.
// 
//</copyright>

//<file>
//
// Name:        progrind.h
//
// Purpose:     interface to progress indicator
//
// Created:     11 Apr 94   Michael Pichler
//
// Changed:     12 Apr 95   Michael Pichler
//
//
//</file>


#ifndef harmony_widgets_progrind_h
#define harmony_widgets_progrind_h

#include "libwidgets.h"
#include <hyperg/hyperg/language.h>

#include <InterViews/patch.h>
class Action;
class Button;
class Deck;
class PolyGlyph;

class FieldBrowser;
class Progress;
class ProgressBar;
class ProgressBase;


// Class Progress - progress indicator
//
// style names: ProgressIndicator
//
// style attribute: background
//
// encloses a progress bar and field browsers with their own style


class ProgressIndicator: public Patch
{
  public:
    ProgressIndicator(                  // constructor (single field)
      HgLanguage::Language lang,        //   language (needed for stop-Button)
      const char* ready,                //   initial ready message
      const char* working,              //   initial working message
      Action* stopaction = nil,         //   optional stop action for stop button
      int listenstop = 0                //   flag whether interested in stopped()
    ): Patch (nil)                      //   (may pass noStopButton)
    {
      float dummy = 1;
      init (lang,
        1, &dummy, ready ? &ready : 0,
        1, &dummy, working ? &working : 0,
        stopaction, listenstop);
    }

    ProgressIndicator(                  // constructor (multiple ready-field)
      HgLanguage::Language lang,        //   language (needed for stop-Button)
      unsigned numreadyfields,          //   no. of fields in ready state
      const float* rsizes,              //   array of field sizes (prop. constants)
      const char** ready,               //   array of initial ready fields
      const char* working,              //   initial working message
      Action* stopaction = nil,         //   optional stop action for stop button
      int listenstop = 0                //   flag whether interested in stopped()
    ): Patch (nil)                      //   (may pass noStopButton)
    {
      float dummy = 1;
      init (lang,
        numreadyfields, rsizes, ready,
        1, &dummy, working ? &working : 0,
        stopaction, listenstop);
    }

    ProgressIndicator(                  // constructor (multiple ready- and working-field)
      HgLanguage::Language lang,        //   language (needed for stop-Button)
      unsigned numreadyfields,          //   no. of fields in ready state
      const float* rsizes,              //   array of field sizes (prop. constants)
      const char** ready,               //   array of initial ready fields
      unsigned numworkingfields,        //   no. of fields in working state
      const float* wsizes,              //   array of field sizes (prop. constants)
      const char** working,             //   array of initial working fields
      Action* stopaction = nil,         //   optional stop action for stop button
      int listenstop = 0                //   flag whether interested in stopped()
    ): Patch (nil)                      //   (may pass noStopButton)
    { init (lang,
        numreadyfields, rsizes, ready,
        numworkingfields, wsizes, working,
        stopaction, listenstop);
    }

    ~ProgressIndicator();

    enum { noStopButton = -1 };

    void readyState(int repair = 1);    // 'ready state': ready msg., no progress bar

    void readyMessage(                  // set message to be displayed in 'ready field'
      const char* msg,                  //   message
      unsigned field = 0,               //   opt. field no.
      int repair = 0                    //   opt. immediate repair
    );

    void workingState(                  // 'working sate': working msg., progress bar, stop button
      float p = 0.0,                    //   initial progress (0.0 by default)
      int repair = 1                    //   opt. immediate repair
    );

    void workingMessage(                // set message to be displayed in 'working state'
      const char* msg,                  //   message
      unsigned field = 0,               //   opt. field no.
      int repair = 0                    //   opt. immediate repair
    );

    void setProgress(                   // set progress
      float p,                          //   to a fraction of 1.0
      int repair = 1                    //   default: immediate repair
    );  

    void increaseProgress(              // increase progress
      float p,                          //   by a fraction of 1.0
      int repair = 1                    //   default: immediate repair
    );  

    float getProgress() const;          // get current progress (0.0 to 1.0)

    void stopAction(                    // set action to be called
      Action* stopaction                //   when stop button is pressed
    );                                  //   button is disabled with nil

    Action* stopAction() const          // get current stop action
    { return stopaction_; }

    int stopped() const                 // has stop button been pressed
    { return stopped_; }                //   in the meantime?

    void clearStop()                    // clear flag for function stop
    { stopped_ = 0; }

    void listenStop(                    // interested in stopped()
      int flag                          //   (0 or 1)
    );

    Progress* getProgressbar() const;   // get progress bar, class Progress
    ProgressBase* getProgressbase () const; // progress bar, abstract base

    void stopButtonAction();            // for callback (internal)

    void repairWindow();                // immediate window repair - implicitly done
                                        // on switching state and setting progress

  private:
    void init(  // constructor container
      HgLanguage::Language lang,
      unsigned numreadyfields, const float* rsizes, const char** ready,
      unsigned numworkingfields, const float* wsizes, const char** working,
      Action* stopaction, int listenstop
    );

    enum { READY, WORKING };
    Deck* deck_;
    int numreadyfields_;
    FieldBrowser** readyfield_;
    int numworkingfields_;
    FieldBrowser** workingfield_;
    ProgressBar* progressbar_;
    Button* stopbutton_;
    Action* stopaction_;
    int listenstop_;
    int stopped_;

};  // ProgressIndicator



#endif
