#pragma once
#include "BuildSettings.h"
#include "pattern.h"
#include <algorithm>
OPENMPT_NAMESPACE_BEGIN
class CSoundFile;
class CPatternContainer
{
public:
CPattern& operator[](const int pat) { return m_Patterns[pat]; }
const CPattern& operator[](const int pat) const { return m_Patterns[pat]; }
public:
CPatternContainer(CSoundFile& sndFile) : m_rSndFile(sndFile) { }
void ClearPatterns();
void DestroyPatterns();
bool Insert(const PATTERNINDEX index, const ROWINDEX rows);
PATTERNINDEX InsertAny(const ROWINDEX rows, bool respectQtyLimits = false);
PATTERNINDEX Duplicate(PATTERNINDEX from, bool respectQtyLimits = false);
void Remove(const PATTERNINDEX index);
template <class Func>
Func ForEachModCommand(PATTERNINDEX nStartPat, PATTERNINDEX nLastPat, Func func);
template <class Func>
Func ForEachModCommand(Func func) { return ForEachModCommand(0, Size() - 1, func); }
std::vector<CPattern>::iterator begin() { return m_Patterns.begin(); }
std::vector<CPattern>::const_iterator begin() const { return m_Patterns.begin(); }
std::vector<CPattern>::const_iterator cbegin() const { return m_Patterns.cbegin(); }
std::vector<CPattern>::iterator end() { return m_Patterns.end(); }
std::vector<CPattern>::const_iterator end() const { return m_Patterns.end(); }
std::vector<CPattern>::const_iterator cend() const { return m_Patterns.cend(); }
PATTERNINDEX Size() const { return static_cast<PATTERNINDEX>(m_Patterns.size()); }
CSoundFile& GetSoundFile() { return m_rSndFile; }
const CSoundFile& GetSoundFile() const { return m_rSndFile; }
bool IsValidIndex(const PATTERNINDEX iPat) const { return (iPat < Size()); }
bool IsValidPat(const PATTERNINDEX iPat) const { return IsValidIndex(iPat) && m_Patterns[iPat].IsValid(); }
bool IsPatternEmpty(const PATTERNINDEX nPat) const;
void ResizeArray(const PATTERNINDEX newSize);
void OnModTypeChanged(const MODTYPE oldtype);
PATTERNINDEX GetNumPatterns() const;
PATTERNINDEX GetNumNamedPatterns() const;
private:
std::vector<CPattern> m_Patterns;
CSoundFile &m_rSndFile;
};
template <class Func>
Func CPatternContainer::ForEachModCommand(PATTERNINDEX nStartPat, PATTERNINDEX nLastPat, Func func)
{
if (nStartPat > nLastPat || nLastPat >= Size())
return func;
for (PATTERNINDEX nPat = nStartPat; nPat <= nLastPat; nPat++) if (m_Patterns[nPat].IsValid())
std::for_each(m_Patterns[nPat].begin(), m_Patterns[nPat].end(), func);
return func;
}
const char FileIdPatterns[] = "mptPc";
void ReadModPatterns(std::istream& iStrm, CPatternContainer& patc, const size_t nSize = 0);
void WriteModPatterns(std::ostream& oStrm, const CPatternContainer& patc);
OPENMPT_NAMESPACE_END