/***************************************************************************
 *   Copyright (C) 2005 by David Saxton                                    *
 *   david@bluehaze.org                                                    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/

#include "ecmosfet.h"
#include "libraryitem.h"
#include "mosfet.h"

#include <KLocalizedString>

#include <QPainter>
#include <QDebug>

Item * ECMOSFET::constructNEM( ItemDocument * itemDocument, bool newItem, const char * id )
{
	return new ECMOSFET( MOSFET::neMOSFET, (ICNDocument*)itemDocument, newItem, id ? id : "nemosfet" );
}
Item * ECMOSFET::constructPEM( ItemDocument * itemDocument, bool newItem, const char * id )
{
	return new ECMOSFET( MOSFET::peMOSFET, (ICNDocument*)itemDocument, newItem, id ? id : "pemosfet" );
}
#if 0
Item * ECMOSFET::constructNDM( ItemDocument * itemDocument, bool newItem, const char * id )
{
	return new ECMOSFET( MOSFET::ndMOSFET, (ICNDocument*)itemDocument, newItem, id ? id : "ndmosfet" );
}
Item * ECMOSFET::constructPDM( ItemDocument * itemDocument, bool newItem, const char * id )
{
	return new ECMOSFET( MOSFET::pdMOSFET, (ICNDocument*)itemDocument, newItem, id ? id : "pdmosfet" );
}
#endif


LibraryItem* ECMOSFET::libraryItemNEM()
{
	return new LibraryItem(
			QStringList(QString("ec/nemosfet")),
// 	i18n("n-e MOSFET"),
	i18n("n-MOSFET"),
	i18n("Discrete"),
	"nemosfet.png",
	LibraryItem::lit_component,
	ECMOSFET::constructNEM );
}


LibraryItem* ECMOSFET::libraryItemPEM()
{
	return new LibraryItem(
			QStringList(QString("ec/pemosfet")),
// 	i18n("p-e MOSFET"),
	i18n("p-MOSFET"),
	i18n("Discrete"),
	"pemosfet.png",
	LibraryItem::lit_component,
	ECMOSFET::constructPEM );
}


#if 0
LibraryItem* ECMOSFET::libraryItemNDM()
{
	return new LibraryItem(
			QStringList(QString("ec/ndmosfet")),
	i18n("n-d MOSFET"),
	i18n("Discrete"),
	"ndmosfet.png",
	LibraryItem::lit_component,
	ECMOSFET::constructNDM );
}


LibraryItem* ECMOSFET::libraryItemPDM()
{
	return new LibraryItem(
			QStringList(QString("ec/pdmosfet")),
	i18n("p-d MOSFET"),
	i18n("Discrete"),
	"pdmosfet.png",
	LibraryItem::lit_component,
	ECMOSFET::constructPDM );
}
#endif


ECMOSFET::ECMOSFET( int MOSFET_type, ICNDocument * icnDocument, bool newItem, const char * id )
	: Component( icnDocument, newItem, id )
{
	m_MOSFET_type = MOSFET_type;
	switch ( (MOSFET::MOSFET_type) m_MOSFET_type )
	{
		case MOSFET::neMOSFET:
		{
			m_name = i18n("N-Channel Enhancement MOSFET");
			break;
		}
		
		case MOSFET::peMOSFET:
		{
			m_name = i18n("P-Channel Enhancement MOSFET");
			break;
		}
		
#if 0
		case MOSFET::ndMOSFET:
		{
			m_name = i18n("N-Channel Depletion MOSFET");
			break;
		}
		
		case MOSFET::pdMOSFET:
		{
			m_name = i18n("P-Channel Depletion MOSFET");
			break;
		}
#endif
	}
	
	setSize( -8, -16, 16, 32 );
	ECNode * NodeS = createPin( 8, 24, 270, "s" );
	m_pMOSFET = createMOSFET( createPin( 8, -24, 90, "d" ), createPin( -16, 8, 0, "g" ), NodeS, NodeS, m_MOSFET_type );
	m_bHaveBodyPin = false;
	
	Variant * v = createProperty( "bodyPin", Variant::Type::Bool );
	v->setCaption( i18nc( "mosfet body/bulk pin", "Body Pin") );
	v->setValue( false );
	
#if 0
	MOSFETSettings s; // will be created with the default settings
	v = createProperty( "I_S", Variant::Type::Double );
	v->setCaption( i18n("Saturation Current") );
	v->setUnit("A");
	v->setMinValue(1e-20);
	v->setMaxValue(1e-0);
	v->setValue( s.I_S );
	v->setAdvanced(true);
	
	v = createProperty( "N_F", Variant::Type::Double );
	v->setCaption( i18n("Forward Coefficient") );
	v->setMinValue(1e0);
	v->setMaxValue(1e1);
	v->setValue( s.N_F );
	v->setAdvanced(true);
	
	v = createProperty( "N_R", Variant::Type::Double );
	v->setCaption( i18n("Reverse Coefficient") );
	v->setMinValue(1e0);
	v->setMaxValue(1e1);
	v->setValue( s.N_R );
	v->setAdvanced(true);
	
	v = createProperty( "B_F", Variant::Type::Double );
	v->setCaption( i18n("Forward Beta") );
	v->setMinValue(1e-1);
	v->setMaxValue(1e3);
	v->setValue( s.B_F );
	v->setAdvanced(true);
	
	v = createProperty( "B_R", Variant::Type::Double );
	v->setCaption( i18n("Reverse Beta") );
	v->setMinValue(1e-1);
	v->setMaxValue(1e3);
	v->setValue( s.B_R );
	v->setAdvanced(true);
#endif
}

ECMOSFET::~ECMOSFET()
{
}


void ECMOSFET::dataChanged()
{
	bool haveBodyPin = dataBool( "bodyPin" );
	if ( haveBodyPin != m_bHaveBodyPin )
	{
		m_bHaveBodyPin = haveBodyPin;
		if ( m_bHaveBodyPin )
		{
			// Creating a body pin
			ECNode * NodeB = createPin( 16, 0, 180, "b" );
			removeElement( m_pMOSFET, false );
			m_pMOSFET = createMOSFET( ecNodeWithID( "d" ), ecNodeWithID( "g" ), ecNodeWithID( "s" ), NodeB, m_MOSFET_type );
		}
		else
		{
			// Removing a body pin
			removeNode( "b" );
			removeElement( m_pMOSFET, false );
			m_pMOSFET = createMOSFET( ecNodeWithID( "d" ), ecNodeWithID( "g" ), ecNodeWithID( "s" ), ecNodeWithID( "s" ), m_MOSFET_type );
		}
	}
	
#if 0
	MOSFETSettings s;
	s.I_S = dataDouble( "I_S" );
	s.N_F = dataDouble( "N_F" );
	s.N_R = dataDouble( "N_R" );
	s.B_F = dataDouble( "B_F" );
	s.B_R = dataDouble( "B_R" );
	
	m_pMOSFET->setMOSFETSettings( s );
#endif
}


void ECMOSFET::drawShape( QPainter & p )
{
	const int _x = int(x());
	const int _y = int(y());
	
	initPainter(p);
	
	// Middle three horizontal lines
	p.drawLine( _x-3, _y-11, _x+8, _y-11 );
	p.drawLine( _x-3, _y, _x+8, _y );
	p.drawLine( _x-3, _y+11, _x+8, _y+11 );
	
	// Right middle vertical line
	if ( m_bHaveBodyPin )
		p.drawLine( _x+8, _y+11, _x+8, _y+16 );
	else
		p.drawLine( _x+8, _y, _x+8, _y+16 );
	
	// Right top vertical line
	p.drawLine( _x+8, _y-11, _x+8, _y-16 );
	
	QPen pen = p.pen();
	pen.setWidth( 2 );
	p.setPen( pen );
	
	// Back line
	p.drawLine( _x-7, _y-10, _x-7, _y+11 );
	
	if ( m_MOSFET_type == MOSFET::neMOSFET ||
			m_MOSFET_type == MOSFET::peMOSFET )
	{
		// Middle three vertical lines
		p.drawLine( _x-2, _y-14, _x-2, _y-7 );
		p.drawLine( _x-2, _y-3, _x-2, _y+4 );
		p.drawLine( _x-2, _y+8, _x-2, _y+15 );
	}
	else
	{
		// Middle vertical line
		p.drawLine( _x-3, _y-14, _x-3, _y+15 );
	}
	
	QPolygon pa(3);
	if ( m_MOSFET_type == MOSFET::neMOSFET /*||
			m_MOSFET_type == MOSFET::ndMOSFET*/ )
	{
		// Inwards facing arrow
		pa[0] = QPoint( 0, 0 );
		pa[1] = QPoint( 5, -3 );
		pa[2] = QPoint( 5, 3 );
	}
	else
	{
		// Outwards facing arrow
		pa[0] = QPoint( 2, -3 );
		pa[1] = QPoint( 7, 0 );
		pa[2] = QPoint( 2, 3 );
	}
	
	pa.translate( _x, _y );
	p.setPen( p.pen().color() );
	p.setBrush( p.pen().color() );
	p.drawPolygon( pa );
	
	deinitPainter(p);
}
