/***************************************************************************
    copyright            : (C) 2003 by Arnold Krille
    email                : arnold@arnoldarts.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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; version 2 of the License.               *
 *                                                                         *
 ***************************************************************************/

#include "krecfilewidgets.h"
#include "krecfilewidgets.moc"

#include "krecfile.h"
#include "krecglobal.h"

#include <kdebug.h>
#include <tdelocale.h>
#include <tqlayout.h>
#include <tqlabel.h>
#include <tqpainter.h>
#include <tqpointarray.h>
#include <tqlineedit.h>
#include <kinputdialog.h>
#include <tqregion.h>
#include <tqrect.h>
#include <tqfont.h>
#include <tqfontmetrics.h>
#include <tdepopupmenu.h>
#include <tdeactionclasses.h>
#include <tdeaction.h>

KRecFileWidget::KRecFileWidget( KRecFile* file, TQWidget* p, const char* n )
  : TQFrame( p,n )
  , _file( 0 )
{
	kdDebug( 60005 ) << k_funcinfo << file << endl;
	setFrameStyle( TQFrame::Panel|TQFrame::Sunken );
	setLineWidth( 1 );
	setMinimumHeight( 20 );

	setFile( file );
}
KRecFileWidget::~KRecFileWidget() {
	kdDebug( 60005 ) << k_funcinfo << endl;
}

void KRecFileWidget::setFile( KRecFile* file ) {
kdDebug( 60005 ) << k_funcinfo << file << endl;
	if ( _file != file ) {
		_file = file;
			//kdDebug( 60005 ) << "Removing widgets" << endl;
			TQValueList<KRecBufferWidget*>::iterator it = bufferwidgets.begin();
			while ( it != bufferwidgets.end() ) {
				delete ( *it );
				++it;
			}
			bufferwidgets.clear();
			resizeEvent();
		if ( _file ) {
			for ( TQValueList<KRecBuffer*>::iterator it = _file->_buffers.begin(); it != _file->_buffers.end(); ++it ) {
				newBuffer( ( *it ) );
			}
			connect( _file, TQ_SIGNAL( sNewBuffer( KRecBuffer* ) ), this, TQ_SLOT( newBuffer( KRecBuffer* ) ) );
			connect( _file, TQ_SIGNAL( sDeleteBuffer( KRecBuffer* ) ), this, TQ_SLOT( deleteBuffer( KRecBuffer* ) ) );
			//kdDebug( 60005 ) << _file->_currentBuffer << endl;
		}
	}
}

void KRecFileWidget::resizeEvent( TQResizeEvent* /*qre*/ ) {
	//kdDebug( 60005 ) << k_funcinfo << endl;
	if ( _file ) {
		int w = contentsRect().width();
		int h = contentsRect().height();
		TQValueList<KRecBufferWidget*>::iterator it;
		for ( it = bufferwidgets.begin(); it != bufferwidgets.end(); ++it ) {
			int width, x;
			if ( !_file->offsetSize()==0 && !( *it )->buffer()->size()==0 ) {
				width = int ( float( ( *it )->buffer()->size() ) / _file->offsetSize() * w );
				x = int( float( ( *it )->buffer()->startpos() ) / _file->size() * w ) + contentsRect().left() ;
			} else {
				width = 5;
				x = contentsRect().left();
			}
			( *it )->setGeometry( x, contentsRect().top(), width, h );
		}
	}
}

void KRecFileWidget::mouseReleaseEvent( TQMouseEvent* qme ) {
	kdDebug( 60005 ) << k_funcinfo << "(" << qme->x() << "|" << qme->y() << ")" << endl;
}

void KRecFileWidget::newBuffer( KRecBuffer* buffer ) {
	//kdDebug( 60005 ) << k_funcinfo << buffer << endl;
	KRecBufferWidget *tmp = new KRecBufferWidget( buffer, this );
	connect( tmp, TQ_SIGNAL( popupMenu( KRecBufferWidget*, TQPoint ) ), this, TQ_SLOT( popupMenu( KRecBufferWidget*, TQPoint ) ) );
	bufferwidgets.append( tmp );
	tmp->show();
	resizeEvent();
}
void KRecFileWidget::deleteBuffer( KRecBuffer* buffer ) {
	//kdDebug( 60005 ) << k_funcinfo << buffer << endl;
	TQValueList<KRecBufferWidget*>::iterator it = bufferwidgets.begin();
	KRecBufferWidget* tmp = 0;
	while ( it != bufferwidgets.end() ) {
		if ( ( *it )->buffer() == buffer ) tmp = ( *it );
		++it;
	}
	if ( tmp != 0 ) {
		delete tmp;
		bufferwidgets.remove( tmp );
	}
}

void KRecFileWidget::popupMenu( KRecBufferWidget* bw, TQPoint pos ) {
	TDEPopupMenu tmp( this );
	TDEToggleAction* _activeaction = new TDEToggleAction( i18n( "Toggle Active/Disabled State" ), TDEShortcut(), this );
	_activeaction->setChecked( bw->buffer()->active() );
	connect( _activeaction, TQ_SIGNAL( toggled( bool ) ), bw->buffer(), TQ_SLOT( setActive( bool ) ) );
	TDEAction* _removeaction = new TDEAction( i18n( "Remove This Part" ), "fileremove", TDEShortcut(), bw->buffer(), TQ_SLOT( deleteBuffer() ), this );
	TDEAction* _changetitle = new TDEAction( i18n( "Change Title of This Part" ), TDEShortcut(), bw, TQ_SLOT( changeTitle() ), this );
	TDEAction* _changecomment = new TDEAction( i18n( "Change Comment of This Part" ), TDEShortcut(), bw, TQ_SLOT( changeComment() ), this );
	_activeaction->plug( &tmp );
	_changetitle->plug( &tmp );
	_changecomment->plug( &tmp );
	tmp.insertSeparator();
	_removeaction->plug( &tmp );

	tmp.exec( pos );

	delete _removeaction;
	delete _changecomment;
	delete _changetitle;
	delete _activeaction;
}



KRecBufferWidget::KRecBufferWidget( KRecBuffer* buffer, TQWidget* p, const char* n )
  : TQFrame( p,n )
  , _buffer( buffer )
  , _main_region( 0 ), _title_region( 0 ), _fileend_region( 0 )
  , alreadyreadsize( 0 )
{
	connect( _buffer, TQ_SIGNAL( somethingChanged() ), this, TQ_SLOT( update() ) );
	kdDebug( 60005 ) << k_funcinfo << endl;
}
KRecBufferWidget::~KRecBufferWidget() {
	kdDebug( 60005 ) << k_funcinfo << endl;
}

void KRecBufferWidget::resizeEvent( TQResizeEvent* ) {
	//kdDebug( 60005 ) << k_funcinfo << endl;
}

void KRecBufferWidget::initLayout() {
	_title_height = fontMetrics().boundingRect( _buffer->filename() ).height() + 4;
	if( height()/5 > _title_height ) _title_height = height()/5;
	int _title_width = fontMetrics().boundingRect( _buffer->filename() ).width() + 10;
	if ( _title_width > width() ) _title_width = width();
	if ( _main_region ) delete _main_region;
	_main_region = new TQRegion( TQRect( 0, _title_height, width(), height()-_title_height ) );
	if ( _title_region ) delete _title_region;
	if ( _buffer->active() )
		_title_region = new TQRegion( TQRect( 0, 0, _title_width, _title_height ) );
	else
		_title_region = new TQRegion( TQRect( 0, _title_height/2, _title_width, _title_height/2 ) );
	if ( _fileend_region ) { delete _fileend_region; _fileend_region=0; }
	if ( _buffer->active() )
		_fileend_region = new TQRegion( TQRect( width()-4, _title_height/2, 4, _title_height/2 ) );
	else
		_fileend_region = new TQRegion( TQRect( width()-4, _title_height/4*3, 4, _title_height/4 ) );

	setMask( _main_region->unite( *_title_region ).unite( *_fileend_region ) );
	
	_topleft = _title_region->boundingRect().topLeft();
	_bottomleft = _main_region->boundingRect().bottomLeft();
	_bottomright = _main_region->boundingRect().bottomRight();
	_topright = _main_region->boundingRect().topRight();
	_bottommiddle = _title_region->boundingRect().bottomRight();
	_bottommiddle += TQPoint( 0, 1 );
	_topmiddle = _title_region->boundingRect().topRight();
}
void KRecBufferWidget::drawFrame( TQPainter* p ) {
	//kdDebug( 60005 ) << k_funcinfo << endl;
	if ( _buffer->active() )
		p->setBrush( colorGroup().highlight() );
	else
		p->setBrush( colorGroup().highlight().dark() );
	p->setPen( TQPen( colorGroup().dark(), 1 ) );
	p->drawRect( _title_region->boundingRect() );
	p->drawRect( _fileend_region->boundingRect() );

	p->setBrush( TQBrush() );
	p->setPen( TQPen( colorGroup().dark(), 1 ) );
	p->drawRect( _main_region->boundingRect() );

	p->setPen( TQPen( colorGroup().highlightedText() ) );
	p->drawText( _title_region->boundingRect(), TQt::AlignCenter, _buffer->title() );

}
void KRecBufferWidget::drawContents( TQPainter* p ) {
	//kdDebug( 60005 ) << k_funcinfo << endl;
	initSamples();
	int space = ( _main_region->boundingRect().height() - 2 ) / 2;
	int xoffset = _main_region->boundingRect().top() + space + 1;
	p->setPen( TQPen( TQColor( 0,0,255 ) ) );
	for ( uint i=0; i<samples1.count(); i++ )
		p->drawPoint( i, int( samples1[ i ]->getMax() * space + xoffset ) );
	for ( uint i=0; i<samples1.count(); i++ )
		p->drawPoint( i, int( samples1[ i ]->getMin() * space + xoffset ) );
	p->setPen( TQPen( TQColor( 255,0,0 ) ) );
	for ( uint i=0; i<samples1.count(); i++ )
		p->drawPoint( i, int( samples1[ i ]->getValue() * space + xoffset ) );
	p->setPen( TQPen( TQColor( 0,0,0 ) ) );
	TQString comment = _buffer->comment();
	if ( comment.isNull() ) comment = i18n( "Lots of Data" );
	p->drawText( _main_region->boundingRect(), TQt::AlignCenter, comment );
}
void KRecBufferWidget::paintEvent( TQPaintEvent* ) {
	initLayout();
	TQPainter *p = new TQPainter( this );
	drawFrame( p );
	drawContents( p );
	delete p;
}

void KRecBufferWidget::mousePressEvent( TQMouseEvent* qme ) {
	kdDebug( 60005 ) << k_funcinfo << endl;
	if ( _main_region->contains( qme->pos() ) || _title_region->contains( qme->pos() ) )
		if ( qme->button() == TQt::RightButton )
			emit popupMenu( this, qme->globalPos() );
}
void KRecBufferWidget::mouseDoubleClickEvent( TQMouseEvent* qme ) {
	if ( _title_region->contains( qme->pos() ) )
		_buffer->setActive( !_buffer->active() );
}

void KRecBufferWidget::initSamples() {
#if 0
	/**
	 * Experimental.
	 *
	 * Doesn't really work since the conversion from char8/char16 to float in
	 * krecfile.cpp isn't working.
	 */
	//kdDebug( 60005 ) << k_funcinfo << endl;
	if ( alreadyreadsize != _buffer->size() ) {
		kdDebug( 60005 ) << k_funcinfo << "something to do" << endl;
		while ( samples1.count() > 0 ) {
			delete samples1.first();
			samples1.pop_front();
		}
		while ( samples2.count() > 0 ) {
			delete samples2.first();
			samples2.pop_front();
		}
		Sample* tmp = new Sample();
		samples1.append( tmp );
		int j=0;
		for ( int i=0; i<= _buffer->sizeInSamples(); ++i ) {
		//for ( int i=0; i<= 10000; ++i ) {
			if ( j/128 ) {
				//kdDebug(60005) << "sample " << i << ": creating new Sample" << endl;
				tmp = new Sample();
				samples1.append( tmp );
				j=0;
			}
			tmp->addValue( _buffer->getSample( i, 0 ) );
			//kdDebug(60005) << "Getting value " << _buffer->getSample( i,0 ) << endl;
			++j;
		}

		tmp = new Sample;
		samples2.append( tmp );
		j=0;
		for ( uint i=0; i<samples1.count(); ++i ) {
			if ( j/128 ) {
				tmp = new Sample();
				samples2.append( tmp );
				j=0;
			}
			tmp->addValue( samples1[ i ]->getValue() );
			++j;
		}

//		for ( uint i=0; i<samples1.count(); ++i )
//			kdDebug(60005) << i << ": " << samples1[ i ]->getMin() << " < " << samples1[ i ]->getValue() << " < " << samples1[ i ]->getMax() << endl;
		for ( uint i=0; i<samples2.count(); ++i )
			kdDebug(60005) << i << ": " << samples2[ i ]->getMin() << " < " << samples2[ i ]->getValue() << " < " << samples2[ i ]->getMax() << endl;

		alreadyreadsize = _buffer->size();
	}
#endif
}


void KRecBufferWidget::changeTitle() {
	TQString tmp = KInputDialog::getText( i18n( "New Title" ), i18n( "Enter new part title:" ), _buffer->title() );
	if ( !tmp.isNull() )
		_buffer->setTitle( tmp );
}
void KRecBufferWidget::changeComment() {
	TQString tmp = KInputDialog::getText( i18n( "New Comment" ), i18n( "Enter new part comment:" ), _buffer->comment() );
	if ( !tmp.isNull() )
		_buffer->setComment( tmp );
}

