// Aseprite
// Copyright (C) 2018-2022  Igara Studio S.A.
// Copyright (C) 2001-2018  David Capello
//
// This program is distributed under the terms of
// the End-User License Agreement for Aseprite.

#ifndef APP_UI_STATUS_BAR_H_INCLUDED
#define APP_UI_STATUS_BAR_H_INCLUDED
#pragma once

#include "app/color.h"
#include "app/context_observer.h"
#include "app/tools/active_tool_observer.h"
#include "app/ui/doc_observer_widget.h"
#include "app/ui/dockable.h"
#include "base/time.h"
#include "doc/tile.h"
#include "ui/base.h"
#include "ui/box.h"

#include <string>
#include <vector>

namespace ui {
class Box;
class Button;
class Entry;
class Label;
class TooltipManager;
class Window;
} // namespace ui

namespace render {
class Zoom;
}

namespace app {
class ButtonSet;
class Editor;
class ZoomEntry;

namespace tools {
class Tool;
}

class StatusBar : public DocObserverWidget<ui::HBox>,
                  public tools::ActiveToolObserver,
                  public Dockable {
  static StatusBar* m_instance;

public:
  static StatusBar* instance() { return m_instance; }

  enum BackupIcon { None, Normal, Small };

  StatusBar(ui::TooltipManager* tooltipManager);
  ~StatusBar();

  void clearText();
  void showDefaultText();
  void showDefaultText(Doc* doc);
  void showAbout();

  bool setStatusText(int msecs, const std::string& text);
  void showTip(int msecs, const std::string& msg);
  void showColor(int msecs, const Color& color, const std::string& text = std::string());
  void showTile(int msecs, doc::tile_t tile, const std::string& text = std::string());
  void showTool(int msecs, tools::Tool* tool);
  void showSnapToGridWarning(bool state);

  // Used by AppEditor to update the zoom level in the status bar.
  void updateFromEditor(Editor* editor);

  void showBackupIcon(BackupIcon icon);

  // Dockable impl
  int dockableAt() const override { return ui::TOP | ui::BOTTOM; }
  int dockHandleSide() const override { return ui::LEFT; }

protected:
  void onInitTheme(ui::InitThemeEvent& ev) override;
  void onResize(ui::ResizeEvent& ev) override;

  // ContextObserver impl
  void onActiveSiteChange(const Site& site) override;

  // DocObserver impl
  void onPixelFormatChanged(DocEvent& ev) override;

  // ActiveToolObserver impl
  void onSelectedToolChange(tools::Tool* tool) override;

private:
  void onCelOpacitySliderChange();
  void newFrame();
  void showNewFramePopupMenu();
  void onChangeZoom(const render::Zoom& zoom);
  void updateSnapToGridWindowPosition();
  void showIndicators();

  base::tick_t m_timeout;

  // About text
  class AboutStatusBar;
  AboutStatusBar* m_about;

  // Indicators
  class Indicators;
  class IndicatorsGeneration;
  Indicators* m_indicators;

  // Box of main commands
  ui::Widget* m_docControls;
  ui::Box* m_commandsBox;
  ui::Label* m_frameLabel;
  ui::Entry* m_currentFrame; // Current frame and go to frame entry
  ui::Button* m_newFrame;    // Button to create a new frame
  ZoomEntry* m_zoomEntry;

  // Tip window
  class CustomizedTipWindow;
  CustomizedTipWindow* m_tipwindow;

  // Snap to grid window
  class SnapToGridWindow;
  SnapToGridWindow* m_snapToGridWindow;
};

} // namespace app

#endif
