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

#include "module.h"
#include "simulator.h"
#include "circuitwidget.h"
#include "circuit.h"
#include "tunnel.h"

#include "doubleprop.h"

#define tr(str) simulideTr("ModuleSubc",str)

ModuleSubc::ModuleSubc( QString type, QString id, QString device )
          : ShieldSubc( type, id, device )
{
    m_subcType = "Module"; 
    setZValue( 2 ); 

    addPropGroup( { tr("Main"), {
new DoubProp<ModuleSubc>( "Z_Value", tr("Z Value"),"", this, &ModuleSubc::zVal, &ModuleSubc::setZVal )
    },0} ); 
}
ModuleSubc::~ModuleSubc(){}

void ModuleSubc::setZVal( double v )
{
    if     ( v < 2 ) v = 2; 
    else if( v > 9 ) v = 9; 
    setZValue( v ); 
}

void ModuleSubc::slotAttach()
{
    double myZ = this->zValue(); 

    QList<QGraphicsItem*> list = this->collidingItems(); 
    QList<BoardSubc*> boardList; 
    for( QGraphicsItem* it : list )
    {
        if( it->type() != UserType+1 ) continue;              // Not a Component

        Component* comp = qgraphicsitem_cast<Component*>( it ); 
        if( !(comp->itemType() == "Subcircuit") ) continue;   // Not a Subcircuit

        BoardSubc* board = (BoardSubc*)comp; 
        if( !board->isBoard() ) continue;             // Not a Board

        QString subcType = board->subcTypeStr(); 
        if( subcType == "Shield" || subcType == "Module" ){
            ShieldSubc* shield = static_cast<ShieldSubc*>(board); 
            if( m_shields.contains( shield ) ) continue;      // Is my child
        }
        boardList.append( board ); 
    }
    for( BoardSubc* board : boardList )
    {
        if( board->zValue() > myZ ) continue;                             // Is above me

        if( Simulator::self()->isRunning() ) CircuitWidget::self()->powerCircOff(); 
        /// FIXME UNDOREDO: Circuit::self()->saveState(); 

        setBoard( board ); 
        m_boardPos = pos() - board->pos(); 
        while( board->parentBoard() ){
            board = board->parentBoard(); 
            m_boardPos -= board->pos(); 
        }
        this->moveTo( m_boardPos ); 
        break; 
    }
}

void ModuleSubc::renameTunnels()
{
    for( Tunnel* tunnel : getPinTunnels() ) tunnel->setName( m_id+"-"+tunnel->tunnelUid() ); 
    for( Tunnel* tunnel : m_subcTunnels   ) tunnel->setName( m_id+"-"+tunnel->tunnelUid() ); 
}
