/***************************************************************************
 *   Copyright (C) 2012 by Santiago González                               *
 *                                                                         *
 ***( see copyright.txt file at root folder )*******************************/

#pragma once

#include <vector>
#include <QList>

#include "e-node.h"

class CircMatrix
{
    typedef std::vector<double>      d_vector_t;
    typedef std::vector<double*>     dp_vector_t;
    typedef std::vector<d_vector_t>  d_matrix_t;
    typedef std::vector<dp_vector_t> dp_matrix_t;

    public:
        CircMatrix();
        ~CircMatrix();

 static CircMatrix* self() { return m_pSelf; }

        void createMatrix( QList<eNode*> &eNodeList );
        bool solveMatrix();

        inline void stampDiagonal( int group, int n, double value ){
            m_admitChanged[group] = true;
            m_circMatrix[n][n] = value;      // eNode numbers start at 1
        }
        inline void stampMatrix( int row, int col, double value ){
            m_circMatrix[row][col] = value;      // eNode numbers start at 1
        }
        inline void stampCoef( int group, int row, double value ){
            m_currChanged[group] = true;
            m_coefVect[row] = value;
        }

    private:
 static CircMatrix* m_pSelf;

        void analyze();
        void addConnections( int enodNum, QList<int>* nodeGroup, QList<int>* allNodes );

        inline void factorMatrix( int n, int group );
        inline bool luSolve( int n, int group );

        int m_numEnodes;
        QList<eNode*>* m_eNodeList;

        QList<dp_matrix_t> m_aList;
        QList<d_matrix_t>  m_aFaList;
        QList<dp_vector_t> m_bList;

        std::vector<bool>    m_admitChanged;
        std::vector<bool>    m_currChanged;
        QList<eNode*>*       m_eNodeActive;
        QList<QList<eNode*>> m_eNodeActList;

        d_matrix_t m_circMatrix;
        d_vector_t m_coefVect;
};
