/* Percolation animation (version 2.02 - Windows)
 *
 * Copyright (C) 2005 N.R. Moloney 
 *
 * Distributed under the Qt Non-Commercial license version 1.0
 */

#include <qapplication.h>
#include <qgroupbox.h>
#include <qlabel.h>
#include <qlcdnumber.h>
#include <qlineedit.h>
#include <qpainter.h>
#include <qpushbutton.h>
#include <qstring.h>
#include <qvbuttongroup.h> 
#include <qwidget.h>

#include "interface.h"
#include "percolation.h"

Interface::Interface( QWidget * parent, const char * name ) : 
  QWidget( parent, name )
{
  Percolation * percolation = new Percolation( this, "percolation" ); 
  percolation->move( offsetx,offsety );
  percolation->resize( 600,600 );

  QVButtonGroup * startAgain = new QVButtonGroup( this, "startAgain" );
  startAgain->move( rightAlign,50 );
  startAgain->resize( buttonWidth,buttonHeight );

  QPushButton * startAgainButton = 
    new QPushButton( "New realisation", startAgain, "startAgainButton" );
  QObject::connect( startAgainButton, SIGNAL( clicked() ), 
		    percolation, SLOT( startNew() ) );
  
  QVButtonGroup * isolate = new QVButtonGroup( this, "isolate" );
  isolate->move( rightAlign,115 );
  isolate->resize( buttonWidth,buttonHeight );

  isolateButton = 
    new QPushButton( "Isolate largest", isolate, "isolateButton" );
  isolateButton->setToggleButton( TRUE );
  QObject::connect( isolateButton, SIGNAL( toggled( bool ) ), 
		    percolation, SLOT( slotIsolate( bool ) ) );
  
  QVButtonGroup * changeSize = new QVButtonGroup( this, "changeSize" );
  changeSize->move( rightAlign,200 );
  changeSize->resize( buttonWidth,150 );

  QPushButton * L600Button = 
    new QPushButton( "L = 600", changeSize, "L600Button" );
  QObject::connect( L600Button, SIGNAL( clicked() ), 
		    percolation, SLOT( startL600() ) ); 
  QPushButton * L300Button = 
    new QPushButton( "L = 300", changeSize, "L300Button" );
  QObject::connect( L300Button, SIGNAL( clicked() ), 
		    percolation, SLOT( startL300() ) ); 
  QPushButton * L150Button = 
    new QPushButton( "L = 150", changeSize, "L150Button" );
  QObject::connect( L150Button, SIGNAL( clicked() ), 
		    percolation, SLOT( startL150() ) ); 

  QGroupBox * changep = new QGroupBox( this, "changep" );
  changep->move( rightAlign,350 );
  changep->resize( buttonWidth,90 );

  QLabel * pLabel = new QLabel( "p = ", changep, "pLabel" );
  pLabel->move( 5,10 );
  QLabel * pcLabel = new QLabel( "pc = 0.59274...", changep, "pcLabel" );
  pcLabel->move( 5,50 );
  p_line_edit = new QLineEdit( changep, "p_line_edit" );
  p_line_edit-> move( 40,10 );
  QObject::connect( p_line_edit, SIGNAL( returnPressed() ), 
		    this, SLOT( slotSetp() ) );

  QPainter paint( this );
  paint.drawText( rightAlign+30,500, "Empty site" );
  paint.drawText( rightAlign+30,520, "Occupied site" );
  paint.drawText( rightAlign+30,540, "Largest cluster" );

  paint.setPen( NoPen );
  paint.setBrush( Qt::blue );
  paint.drawRect( rightAlign,490, 10,10 );
  paint.setBrush( Qt::yellow );
  paint.drawRect( rightAlign,510, 10,10 );
  paint.setBrush( Qt::red );
  paint.drawRect( rightAlign,530, 10,10 );

  QGroupBox * system_size = 
    new QGroupBox( "System size L", this, "system_size" );
  system_size->move( leftAlign,100 );
  system_size->resize( buttonWidth,boxHeight );

  systemSizeLCD = new QLCDNumber( 3, system_size, "systemSizeLCD" );
  systemSizeLCD->setGeometry( 30,30, 100,50 );
  systemSizeLCD->setSegmentStyle( QLCDNumber::Filled );

  QGroupBox * probability = 
    new QGroupBox( "Occupation prob. p", this, "probability" );
  probability->move( leftAlign,300 );
  probability->resize( buttonWidth,boxHeight );
  QObject::connect( percolation, SIGNAL( sizeChanged( int ) ), 
		    this, SLOT( slotSetSize( int ) ) );  
  QObject::connect( this, SIGNAL( pChanged( double ) ), 
		    percolation, SLOT( pChanged( double ) ) );
  
  probabilityLCD = new QLCDNumber( 6, probability, "probabilityLCD" );
  probabilityLCD->setGeometry( 30,30, 100,50 );
  probabilityLCD->setMode( QLCDNumber::DEC );
  probabilityLCD->setSegmentStyle( QLCDNumber::Filled );
  probabilityLCD->display( percolation->p ); 

  QGroupBox * largest_cluster = 
    new QGroupBox( "Largest cluster size", this, "largest_cluster" );
  largest_cluster->move( leftAlign,500 );
  largest_cluster->resize( buttonWidth,boxHeight );
 
  largestClusterLCD = 
    new QLCDNumber( 6, largest_cluster, "largestClusterLCD" );
  largestClusterLCD->setGeometry( 30,30, 100,50 );
  largestClusterLCD->setSegmentStyle( QLCDNumber::Filled );
  QObject::connect( percolation, SIGNAL( largestChanged( int ) ), 
		    this, SLOT( slotSetLargest( int ) ) );  

  percolation->callLargest();
  percolation->callSize();

  QVButtonGroup * exit = new QVButtonGroup( this, "exit" );
  exit->move( rightAlign,595 );
  exit->resize( buttonWidth,buttonHeight );

  QPushButton * exitButton = new QPushButton( "Quit", exit, "exitButton" );
  QObject::connect( exitButton, SIGNAL( clicked() ), qApp, SLOT( quit() ) );

}

///////////////////////////////////////////////////

void Interface::slotSetp()
{
  int i;
  unsigned int decimal = 0;

  p_typed = p_line_edit->text();

  if( p_typed[0] == '.' )
  {
    p_typed.prepend( '0' );
  }
  
  for( i = 0; i < int(p_typed.length()); i++ )
  {
    if( (!p_typed[i].isDigit()) && (p_typed[i] != '.') )
    {
      p_line_edit->setText( "" );
      return;
    }
    if( p_typed[i] == '.' )
    {
      decimal++;
      if( decimal > 1 )
      {
	p_line_edit->setText( "" );
	return;
      }
    }
  }

  if( p_typed.length() > 2 )
  {
    if( (p_typed[1] != '.') ) 
    {
      p_line_edit->setText( "" );
      return;
    }
  }

  if( (p_typed[0] == '1' ) && (p_typed.length() > 1) )
  {
    for( i = 2; i < int(p_typed.length()); i++ )
    {
      if( p_typed[i] != '0' )
      {
	p_line_edit->setText( "" );
	return;
      }
    }
  }

  if( p_typed.length() > 6 ) 
  {
    p_typed.truncate( 6 );
  }

  probabilityLCD->display( p_typed.toDouble() );
  p_line_edit->clearFocus();

  emit pChanged( p_typed.toDouble() );

  return;
}

///////////////////////////////////////////////////

void Interface::slotSetSize( int L )
{
  systemSizeLCD->display( L );
  
  return;
}

///////////////////////////////////////////////////

void Interface::slotSetLargest( int largest )
{
  largestClusterLCD->display( largest );

  return;
}

///////////////////////////////////////////////////

void Interface::paintEvent( QPaintEvent * )
{
  QPainter paint( this );
  paint.drawText( rightAlign+30,500, "Empty site" );
  paint.drawText( rightAlign+30,520, "Occupied site" );
  paint.drawText( rightAlign+30,540, "Largest cluster" );

  paint.setPen( NoPen );
  paint.setBrush( Qt::blue );
  paint.drawRect( rightAlign,490, 10,10 );
  paint.setBrush( Qt::yellow );
  paint.drawRect( rightAlign,510, 10,10 );
  paint.setBrush( Qt::red );
  paint.drawRect( rightAlign,530, 10,10 );

  return;
}


