// ProgressDialog.h

#ifndef __PROGRESS_DIALOG_H
#define __PROGRESS_DIALOG_H

#include "../../../Windows/Synchronization.h"
#include "../../../Windows/Thread.h"

#include "../../../Windows/Control/Dialog.h"
#include "../../../Windows/Control/ProgressBar.h"

#include "ProgressDialogRes.h"

class CProgressSync
{
  NWindows::NSynchronization::CCriticalSection _cs;
  bool _stopped;
  bool _paused;
  UInt64 _total;
  UInt64 _completed;
public:
  CProgressSync(): _stopped(false), _paused(false), _total(1), _completed(0) {}

  HRESULT ProcessStopAndPause();
  bool GetStopped()
  {
    NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
    return _stopped;
  }
  void SetStopped(bool value)
  {
    NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
    _stopped = value;
  }
  bool GetPaused()
  {
    NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
    return _paused;
  }
  void SetPaused(bool value)
  {
    NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
    _paused = value;
  }
  void SetProgress(UInt64 total, UInt64 completed)
  {
    NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
    _total = total;
    _completed = completed;
  }
  void SetPos(UInt64 completed)
  {
    NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
    _completed = completed;
  }
  void GetProgress(UInt64 &total, UInt64 &completed)
  {
    NWindows::NSynchronization::CCriticalSectionLock lock(_cs);
    total = _total;
    completed = _completed;
  }
};

class CU64ToI32Converter
{
  UInt64 _numShiftBits;
public:
  void Init(UInt64 range)
  {
    // Windows CE doesn't like big number here.
    for (_numShiftBits = 0; range > (1 << 15); _numShiftBits++)
      range >>= 1;
  }
  int Count(UInt64 value) { return int(value >> _numShiftBits); }
};

class CProgressDialog: public NWindows::NControl::CModalDialog
{
private:
  UINT_PTR _timer;

  UString _title;
  CU64ToI32Converter _converter;
  UInt64 _peviousPos;
  UInt64 _range;
  NWindows::NControl::CProgressBar m_ProgressBar;

  int _prevPercentValue;

  bool _wasCreated;
  bool _needClose;
  bool _inCancelMessageBox;
  bool _externalCloseMessageWasReceived;

  bool OnTimer(WPARAM timerID, LPARAM callback);
  void SetRange(UInt64 range);
  void SetPos(UInt64 pos);
  virtual bool OnInit();
  virtual void OnCancel();
  virtual void OnOK();
  NWindows::NSynchronization::CManualResetEvent _dialogCreatedEvent;
  #ifndef _SFX
  void AddToTitle(LPCWSTR string);
  #endif
  bool OnButtonClicked(int buttonID, HWND buttonHWND);

  void WaitCreating() { _dialogCreatedEvent.Lock(); }
  void CheckNeedClose();
  bool OnExternalCloseMessage();
public:
  CProgressSync Sync;
  int IconID;

  #ifndef _SFX
  HWND MainWindow;
  UString MainTitle;
  UString MainAddTitle;
  ~CProgressDialog();
  #endif

  CProgressDialog(): _timer(0)
    #ifndef _SFX
    ,MainWindow(0)
    #endif
  {
    IconID = -1;
    _wasCreated = false;
    _needClose = false;
    _inCancelMessageBox = false;
    _externalCloseMessageWasReceived = false;

    if (_dialogCreatedEvent.Create() != S_OK)
      throw 1334987;
  }

  INT_PTR Create(const UString &title, NWindows::CThread &thread, HWND wndParent = 0)
  {
    _title = title;
    INT_PTR res = CModalDialog::Create(IDD_PROGRESS, wndParent);
    thread.Wait();
    return res;
  }

  enum
  {
    kCloseMessage = WM_APP + 1
  };

  virtual bool OnMessage(UINT message, WPARAM wParam, LPARAM lParam);

  void ProcessWasFinished()
  {
    WaitCreating();
    if (_wasCreated)
      PostMessage(kCloseMessage);
    else
      _needClose = true;
  };
};


class CProgressCloser
{
  CProgressDialog *_p;
public:
  CProgressCloser(CProgressDialog &p) : _p(&p) {}
  ~CProgressCloser() { _p->ProcessWasFinished(); }
};

#endif
