#ifndef _PINMUX_H_
#define _PINMUX_H_
//----------------------------------------------------------------------------
///
/// \file   pinmux.h
///
/// \brief  See implementation for further details
///
/// \date   20180129
/// \author Maximilian Seesslen <mes@seesslen.net>
///
//----------------------------------------------------------------------------


//---Documentation------------------------------------------------------------


//---Includes -----------------------------------------------------------------


//---General--------------------------

#include <QList>
#include <QJsonObject>

//---Own------------------------------

#include "periphery.h"
#include "periphery_list.h"
#include "constructor.h"


//--- Declaration -------------------------------------------------------------


class CApp;
class CBoard;

class CPinmux
{
   private:
      QStringList irqHandlers;

      CApp *m_pApp;
      CBoard *m_pBoard;

      int m_loops=0;

   public:
      enum EMethod{
               random,
               shuffle,
               linear
      };

      CPinmux()
         :m_pApp(nullptr)
         ,m_pBoard(nullptr)
      {}
      void setBoardApp(CBoard &board, CApp &app)
      {
         m_pApp=&app;
         m_pBoard=&board;
      }

      const CApp *getApp() const
      {
         return(m_pApp);
      }
      CApp *getApp()
      {
         return(m_pApp);
      }
      const CBoard *getBoard() const
      {
         return(m_pBoard);
      }
      CBoard *getBoard()
      {
         return(m_pBoard);
      }

      void resolveApp( EMethod eMethod = EMethod::random );
      //CPeripheryPtr resolveReference(CReference &periphery, const CReference &rootReference);
      CPeripheryPtr resolveReference(CReference &reference, const CReference &rootReference, const QString &group);
      bool skipConsume(const CPeriphery &periphery, const CReference &reference);
      bool resolveConsumes(CPeriphery &periphery, const CReference &rootReference);
      bool resolveConsumes(CPeriphery &periphery, const CReference &rootReference, const QString &group);
      void usePeriphery(CPeriphery &periphery, CReference &reference, CReference &rootReference, bool instantiate);
      void addProvides(CPeriphery &periphery);
      const CConstructor *getConstructor(const CPeriphery &periphery) const;
      //QList<QString> getPeripheralArguments(const CPeriphery &periphery) const;
      const QStringList &getIrqHandlers() const
      {
         return(irqHandlers);
      }
      void generateIrqList();
#if 0
      void addConstructor(const CConstructor &constructor)
      {
         m_constructorPool.addConstructor(constructor);
      }
#endif
      void dump(QString fileName);
      void reOrder();
      void reset();
      bool checkFinished(CReferencePtr *ptr=nullptr);
      void resolvePrefered();
      void resolveByRandom();
      void resolveLinear();
      void resolveByShuffle();
      void checkPlausibility();
      int getLoops() const
      {
         return(m_loops);
      }
      void linkConstructors();
      void errorExit(QString message) const;
      void resolveErrorExit(CReference &reference) const;
      void checkFabricate( CPeriphery &periphery );
      //CPeripheryPtr checkFabricateList( CPeripheryPtr periphery );
      QSharedPointer<CPeriphery> checkFabricateList( QSharedPointer<CPeriphery> periphery );
#if 0
      const CConstructorPool &getConstructorPool() const
      {
         return( m_constructorPool );
      }
#endif
      /**
       * @brief filter subset of application due to a new variant
       */
      void filterSubsetVariant( const QString& variant );
};


//---fin----------------------------------------------------------------------
#endif // ? ! _PINMUX_H_
