// Aseprite
// Copyright (C) 2018-2024  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_DOC_OBSERVER_H_INCLUDED
#define APP_DOC_OBSERVER_H_INCLUDED
#pragma once

namespace doc {
class Remap;
}

namespace app {
class Doc;
class DocEvent;

class DocObserver {
public:
  virtual ~DocObserver() {}

  virtual void onCloseDocument(Doc* doc) {}
  virtual void onFileNameChanged(Doc* doc) {}

  // General update. If an observer receives this event, it's because
  // anything in the document could be changed.
  virtual void onGeneralUpdate(DocEvent& ev) {}

  virtual void onColorSpaceChanged(DocEvent& ev) {}
  virtual void onPixelFormatChanged(DocEvent& ev) {}
  virtual void onPaletteChanged(DocEvent& ev) {}

  virtual void onAddLayer(DocEvent& ev) {}
  virtual void onAddFrame(DocEvent& ev) {}
  virtual void onAddCel(DocEvent& ev) {}
  virtual void onAddSlice(DocEvent& ev) {}
  virtual void onAddTag(DocEvent& ev) {}

  virtual void onBeforeRemoveLayer(DocEvent& ev) {}
  virtual void onAfterRemoveLayer(DocEvent& ev) {}

  // Called when a frame is removed. It's called after the frame was
  // removed, and the sprite's total number of frames is modified.
  virtual void onRemoveFrame(DocEvent& ev) {}
  virtual void onRemoveTag(DocEvent& ev) {}
  virtual void onBeforeRemoveCel(DocEvent& ev) {}
  virtual void onAfterRemoveCel(DocEvent& ev) {}
  virtual void onRemoveSlice(DocEvent& ev) {}

  virtual void onSpriteSizeChanged(DocEvent& ev) {}
  virtual void onSpriteTransparentColorChanged(DocEvent& ev) {}
  virtual void onSpritePixelRatioChanged(DocEvent& ev) {}
  virtual void onSpriteGridBoundsChanged(DocEvent& ev) {}

  virtual void onLayerNameChange(DocEvent& ev) {}
  virtual void onLayerOpacityChange(DocEvent& ev) {}
  virtual void onLayerBlendModeChange(DocEvent& ev) {}
  virtual void onLayerRestacked(DocEvent& ev) {}
  virtual void onLayerMergedDown(DocEvent& ev) {}

  virtual void onCelMoved(DocEvent& ev) {}
  virtual void onCelCopied(DocEvent& ev) {}
  virtual void onCelFrameChanged(DocEvent& ev) {}
  virtual void onCelPositionChanged(DocEvent& ev) {}
  virtual void onCelOpacityChange(DocEvent& ev) {}
  virtual void onCelZIndexChange(DocEvent& ev) {}

  virtual void onUserDataChange(DocEvent& ev) {}

  virtual void onFrameDurationChanged(DocEvent& ev) {}

  virtual void onImagePixelsModified(DocEvent& ev) {}
  virtual void onSpritePixelsModified(DocEvent& ev) {}
  virtual void onExposeSpritePixels(DocEvent& ev) {}

  // When the number of total frames available is modified.
  virtual void onTotalFramesChanged(DocEvent& ev) {}

  // The selection has changed.
  virtual void onSelectionChanged(DocEvent& ev) {}
  virtual void onSelectionBoundariesChanged(DocEvent& ev) {}

  // When the tag range changes
  virtual void onTagChange(DocEvent& ev) {}

  // When the tag is renamed
  virtual void onTagRename(DocEvent& ev) {}

  // Slices
  virtual void onSliceNameChange(DocEvent& ev) {}

  // The tileset has changed.
  virtual void onTilesetChanged(DocEvent& ev) {}

  // The collapsed/expanded flag of a specific layer changed.
  virtual void onLayerCollapsedChanged(DocEvent& ev) {}

  // The visibility flag of a specific layer is going to change/changed.
  virtual void onBeforeLayerVisibilityChange(DocEvent& ev, bool newState) {}
  virtual void onAfterLayerVisibilityChange(DocEvent& ev) {}

  // The editable flag of a specific layer is going to change/changed.
  virtual void onBeforeLayerEditableChange(DocEvent& ev, bool newState) {}

  // The tileset was remapped (e.g. when tiles are re-ordered).
  virtual void onRemapTileset(DocEvent& ev, const doc::Remap& remap) {}

  // When the tile management plugin property is changed.
  virtual void onTileManagementPluginChange(DocEvent& ev) {}

  // When a new tilemap cel/tile is created in certain situations,
  // like after drawing in an empty tilemap cel, or when we paste a
  // cel into an empty tilemap cel, so a new tile is created.
  //
  // This is useful for a tile management plugin to know when a new
  // tile is added automatically by the editor or the timeline
  // through draw_image_into_new_tilemap_cel(), and the plugin can
  // do some extra work with it.
  //
  // Warning: This must be triggered from the UI thread (because
  // scripts will listen this event).
  virtual void onAfterAddTile(DocEvent& ev) {}
};

} // namespace app

#endif
