// Aseprite Document Library
// Copyright (c) 2019-2022 Igara Studio S.A.
// Copyright (c) 2001-2017 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.

#ifndef DOC_PALETTE_PICKS_H_INCLUDED
#define DOC_PALETTE_PICKS_H_INCLUDED
#pragma once

#include "base/debug.h"
#include "doc/color.h"

#include <algorithm>
#include <vector>

namespace doc {

  class PalettePicks {
  public:
    typedef std::vector<bool> list_type;
    typedef list_type::iterator iterator;
    typedef list_type::const_iterator const_iterator;
    typedef list_type::reference reference;
    typedef list_type::const_reference const_reference;

    PalettePicks() { }
    PalettePicks(int n) : m_items(n, false) { }

    int size() const { return int(m_items.size()); }
    int picks() const { return (int)std::count(m_items.begin(), m_items.end(), true); }

    iterator begin() { return m_items.begin(); }
    iterator end() { return m_items.end(); }

    const_iterator begin() const { return m_items.begin(); }
    const_iterator end() const { return m_items.end(); }

    const_reference operator[](int idx) const {
      ASSERT(idx >= 0 && idx < int(m_items.size()));
      return m_items[idx];
    }

    reference operator[](int idx) {
      ASSERT(idx >= 0 && idx < int(m_items.size()));
      return m_items[idx];
    }

    void resize(int n) {
      m_items.resize(n, false);
    }

    void clear() {
      std::fill(m_items.begin(), m_items.end(), false);
    }

    void all() {
      std::fill(m_items.begin(), m_items.end(), true);
    }

    // If there is just one selected color (or none), we select them all.
    void pickAllIfNeeded() {
      if (picks() < 2)
        all();
    }

    int firstPick() const {
      for (int i=0; i<size(); ++i)
        if (m_items[i])
          return i;
      return -1;
    }

    int lastPick() const {
      for (int i=size()-1; i>=0; --i)
        if (m_items[i])
          return i;
      return -1;
    }

    std::vector<color_t> toVectorOfIndexes() const {
      std::vector<color_t> result(picks());
      for (color_t i=0, j=0; i<(color_t)size(); ++i) {
        if (m_items[i])
          result[j++] = i;
      }
      return result;
    }

    void invert() {
      for (int i=0; i<size(); ++i)
        m_items[i] = !m_items[i];
    }

  private:
    list_type m_items;
  };

} // namespace doc

#endif
