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

#include "shield.h"
#include "circuitwidget.h"
#include "simulator.h"
#include "circuit.h"
#include "tunnel.h"
#include "node.h"
#include "e-node.h"
//#include "utils.h"

#include "stringprop.h"
#include "boolprop.h"
#include "doubleprop.h"

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

ShieldSubc::ShieldSubc( QString type, QString id, QString device )
          : BoardSubc( type, id, device )
{
    m_subcType = "Shield"; 
    m_boardId = ""; 
    setZValue( 1 ); 

    addPropGroup( {"Hidden", {
        new StrProp<ShieldSubc>( "BoardId", "",""
                               , this, &ShieldSubc::boardId, &ShieldSubc::setBoardId )
    }, groupHidden} ); 
}
ShieldSubc::~ShieldSubc(){}

void ShieldSubc::setBoard( BoardSubc* board )
{
    m_parentBoard = board; 
    m_boardId = board->getUid(); 
    board->attachShield( this ); 
    if( m_subcType == "Shield" ) attachToBoard(); 
    setParentItem( board ); 
    Circuit::self()->compList()->removeOne( this ); 
}

void ShieldSubc::connectBoard()
{
    m_parentBoard = nullptr; 
    if( m_boardId == "" ) return; 

    QString name = Circuit::self()->origId( m_boardId ); 
    if( name != "" ) m_boardId = name; 

    Component* comp = Circuit::self()->getCompById( m_boardId ); 
    if( comp && comp->itemType() == "Subcircuit" )
    {
        m_parentBoard = static_cast<BoardSubc*>(comp); 
        setBoard( m_parentBoard ); 
}   }

void ShieldSubc::slotAttach()
{
    QList<QGraphicsItem*> list = this->collidingItems(); 
    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->subcTypeStr() != "Board") continue;            // Not a Board

        if( board->logicSymbol() ) continue;                  // Don't attach to logic symbol

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

        setBoard( board ); 
        break; 
    }
}

void ShieldSubc::attachToBoard()
{
    int origX = 8*(m_parentBoard->pkgWidth()-m_width)/2; 
    m_boardPos = QPointF(origX, 0); 
    this->moveTo( m_boardPos ); 
    this->setRotation(0); 
    for( Tunnel* tunnel : m_subcTunnels ) tunnel->setName( m_boardId+"-"+tunnel->tunnelUid() ); 
}

void ShieldSubc::slotDetach()
{
    if( !m_parentBoard ) return; 

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

    this->moveTo( this->scenePos()+QPointF( 8,-8 ) ); 
    m_parentBoard->detachShield( this ); 
    m_boardId = ""; 
    m_parentBoard = nullptr; 
    setParentItem( nullptr ); 
    Circuit::self()->compList()->append( this ); 
    renameTunnels(); 
}

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

void ShieldSubc::contextMenuEvent( QGraphicsSceneContextMenuEvent* event )
{
    event->accept(); 
    QMenu* menu = new QMenu(); 
    contextMenu( event, menu ); 
    menu->deleteLater(); 
}

void ShieldSubc::contextMenu( QGraphicsSceneContextMenuEvent* event, QMenu* menu )
{
    event->accept(); 

    if( m_parentBoard )
    {
        QAction* detachAction = menu->addAction( m_theme->icon(":/detach.png"),tr("Detach") ); 
        QObject::connect( detachAction, &QAction::triggered, [=](){ slotDetach();  } ); 

        addMainCompsMenu( menu );  // My main comps

        menu->addAction( m_theme->icon(":/null-0.png"), "" ); 
        menu->addSection( m_parentBoard->idLabel()+" (parent)" );  // Parent section
        m_parentBoard->contextMenu( event, menu ); 
    }else{
        QAction* attachAction = menu->addAction( m_theme->icon(":/attach.png"),tr("Attach") ); 
        QObject::connect( attachAction, &QAction::triggered, [=](){ slotAttach();  } ); 
        SubCircuit::contextMenu( event, menu ); 
    }
}
