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

#include "dectobcd.h"
#include "itemlibrary.h"
#include "circuit.h"
#include "iopin.h"

#include "boolprop.h"

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

Component* DecToBcd::construct( QString type, QString id )
{ return new DecToBcd( type, id );  }

LibraryItem* DecToBcd::libraryItem()
{
    return new LibraryItem(
        tr("Encoder(10/16 to 4)"),
        "Converters",
        "3to2g.png",
        "DecToBcd",
        DecToBcd::construct ); 
}

DecToBcd::DecToBcd( QString type, QString id )
        : LogicComponent( type, id )
{
    m_width  = 4; 
    m_height = 10; 

    m_tristate = true; 
    m_16Bits = false; 
    m_bits = 10; 

    QStringList pinList; 

    pinList// Outputs:
            << "OR03 A"
            << "OR04 B"
            << "OR05 C"
            << "OR06 D"
            ; 
    init( pinList ); 

    setNumInps( 10,"D", 1 ); 

    createOePin( "IU03OE ", id+"-in15");  // Output Enable

    addPropGroup( { tr("Main"), {
        new BoolProp<DecToBcd>("_16_Bits", tr("16 Bits"),""
                              , this, &DecToBcd::is16Bits, &DecToBcd::set16bits, propNoCopy ),
    }, groupNoCopy } ); 

    appendPropGroup( tr("Main"), IoComponent::familyProps() ); 

    addPropGroup( { tr("Inputs")
        , IoComponent::inputProps()
        +QList<ComProperty*>({
        new BoolProp<DecToBcd>("Invert_Inputs", tr("Invert Inputs"),""
                              , this, &DecToBcd::invertInps, &DecToBcd::setInvertInps, propNoCopy )
        })
    ,0 } ); 

    addPropGroup( { tr("Outputs")
        , IoComponent::outputProps()
        + IoComponent::outputType()
        + QList<ComProperty*>({
            new BoolProp<DecToBcd>("Tristate", tr("Tristate"),""
                                   , this, &DecToBcd::tristate, &DecToBcd::setTristate ),
        })
    ,0 } ); 

    addPropGroup( { tr("Timing"), IoComponent::edgeProps(),0 } ); 
}
DecToBcd::~DecToBcd(){}

void DecToBcd::stamp()
{
    for( uint i=0;  i<m_inpPin.size();  ++i ) m_inpPin[i]->changeCallBack( this ); 
    LogicComponent::stamp(); 
}

void DecToBcd::voltChanged()
{
    if( m_tristate ) LogicComponent::updateOutEnabled(); 

    int i; 
    for( i=m_bits-2;  i>=0;  --i )
    {
        if( m_inpPin[i]->getInpState() ) break; 
    }
    m_nextOutVal = i+1; 
    scheduleOutPuts( this ); 
}

void DecToBcd::set16bits( bool set )
{
    m_bits =  set ? 16 : 10; 
    m_16Bits = set; 
    setNumInps( m_16Bits ? 16 : 10, "D", 1 ); 
    m_oePin->setY( m_area.y()-8 ); 
}
