/***************************************************************************
 *   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 "bidirled.h"
#include "colorcombo.h"
#include "diode.h"
#include "ecled.h"
#include "ecnode.h"
#include "libraryitem.h"
#include "simulator.h"

#include <tdelocale.h>
#include <tqpainter.h>

Item* BiDirLED::construct( ItemDocument *itemDocument, bool newItem, const char *id )
{
	return new BiDirLED( (ICNDocument*)itemDocument, newItem, id );
}

LibraryItem* BiDirLED::libraryItem()
{
	return new LibraryItem (
		"ec/bidir_led",
		i18n("Bidirectional LED"),
		i18n("Outputs"),
		"bidirled.png",
		LibraryItem::lit_component,
		BiDirLED::construct
						   );
}

BiDirLED::BiDirLED( ICNDocument *icnDocument, bool newItem, const char *id )
	: Component( icnDocument, newItem, id ? id : "bidir_led" )
{
	m_name = i18n("Bidirectional LED");
	m_desc = i18n("Bidrectional Light Emitting Diode");
	m_bDynamicContent = true;
	
	setSize( -8, -16, 16, 32 );
	init1PinLeft();
	init1PinRight();
	setSize( -8, -24, 24, 40 );
	
	m_pDiode[0] = createDiode( m_pNNode[0], m_pPNode[0] );
	m_pDiode[1] = createDiode( m_pPNode[0], m_pNNode[0] );
	
	avg_brightness[0] = avg_brightness[1] = 255;
	lastUpdatePeriod = 0.;
	r[0]=r[1]=g[0]=g[1]=b[0]=b[1]=0;
	last_brightness[0] = last_brightness[1] = 255;
	
	createProperty( "0-color1", Variant::Type::Color );
	property("0-color1")->setCaption( i18n("Color 1") );
	property("0-color1")->setColorScheme( ColorCombo::LED );
	
	createProperty( "0-color2", Variant::Type::Color );
	property("0-color2")->setCaption( i18n("Colour 2") );
	property("0-color2")->setColorScheme( ColorCombo::LED );
}

BiDirLED::~BiDirLED()
{
}

void BiDirLED::dataChanged()
{
	TQString colors[] = { "0-color1", "0-color2" };
	for ( unsigned i = 0; i < 2; i++ )
	{
		TQColor color = dataColor(colors[i]);
		r[i] = color.red();
		g[i] = color.green();
		b[i] = color.blue();
		r[i] /= 0x100;
		g[i] /= 0x100;
		b[i] /= 0x100;
	}
}

void BiDirLED::stepNonLogic()
{
	double interval = 1./LINEAR_UPDATE_RATE;
	lastUpdatePeriod += interval;
	
	for ( unsigned i = 0; i < 2; i++ )
		avg_brightness[i] += ECLed::brightness(m_pDiode[i]->current())*interval;
}

void BiDirLED::drawShape( TQPainter &p )
{
	initPainter(p);
	
	for ( unsigned i = 0; i < 2; i++ )
	{
		uint _b;
		if ( lastUpdatePeriod == 0. )
			_b = last_brightness[i];
		
		else
		{
			_b = uint(avg_brightness[i]/lastUpdatePeriod);
			last_brightness[i] = _b;
		}
		avg_brightness[i] = 0.;
	
		p.setBrush( TQColor( uint(255-(255-_b)*(1-r[i])), uint(255-(255-_b)*(1-g[i])), uint(255-(255-_b)*(1-b[i])) ) );
		
		
		TQPointArray pa(3);
		if ( i == 0 )
		{
			pa[0] = TQPoint( 8, -8 );
			pa[1] = TQPoint( -8, -16 );
			pa[2] = TQPoint( -8, 0 );
		}
		else
		{
			pa[0] = TQPoint( -8, 8 );
			pa[1] = TQPoint( 8, 0 );
			pa[2] = TQPoint( 8, 16 );
		}
		
		pa.translate( int(x()), int(y()) );
		p.drawPolygon(pa);
		p.drawPolyline(pa);
	}
	lastUpdatePeriod = 0.;
		
	// Draw the arrows indicating it's a LED
	int _x = (int)x()-2;
	int _y = (int)y()-21;
	
	p.drawLine( _x+9, _y+3, _x+12, _y ); // Tail of left arrow
	p.drawLine( _x+12, _y, _x+10, _y ); // Left edge of left arrow tip
	p.drawLine( _x+12, _y, _x+12, _y+2 ); // Right edge of left arrow tip
	
	p.drawLine( _x+12, _y+6, _x+15, _y+3 ); // Tail of right arrow
	p.drawLine( _x+15, _y+3, _x+13, _y+3 ); // Left edge of right arrow tip
	p.drawLine( _x+15, _y+3, _x+15, _y+5 ); // Right edge of right arrow tip
	
	p.drawLine( _x+10, _y, _x+15, _y+5 ); // Diagonal line that forms base of both arrow tips
	
	_x = int(x());
	_y = int(y());
	p.drawLine( _x+8, _y-16, _x+8, _y );
	p.drawLine( _x-8, _y, _x-8, _y+16 );
	
	deinitPainter(p);
}

