/***************************************************************************
 *   Copyright (C) 2004 by Trenton Carr                                    *
 *   trenton.carr@gmail.com                                                *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA.             *
 ***************************************************************************/

#include <math.h>
#include <qlayout.h>
#include <qcheckbox.h>
//Added by qt3to4:
#include <Q3VBoxLayout>
#include <QPaintEvent>
#include <klocale.h>
#include <knuminput.h>
#include <krestrictedline.h>

#include <trigview.h>

#include <../kplotwidget.h>
#include <deg_theta.h>

TrigView::TrigView(QWidget* parent, const char* name, WFlags fl)
        : TrigViewD(parent,name,fl)
{
    QWidget *viewPlot = new QWidget (TrigFrame, 0);

    Q3VBoxLayout *vlay1 = new Q3VBoxLayout( viewPlot, 0, -1 );

    pw = new KPlotWidget( -100.0, 100.0, -100.0, 100.0, viewPlot);

    deg = new Deg_Theta();

    pw->setShowAxes( false );
    pw->setShowTickMarks( false );
    pw->setBGColor( QColor( "black" ) );
    pw->setFGColor( QColor ( "white") );
    pw->setCartesian( true );
    pw->setShowCartAxis( true );
    pw->setShowCartTickMarks( true );
    pw->setShowCartTickLabels( true );
    pw->setShowDegreeCircle( true );

    vlay1->addWidget( pw );

    viewPlot->resize( 450, 450 );

    connect( spin, SIGNAL(valueChanged( double )), deg, SLOT( setAngle( double )) );
	connect( spin_radius, SIGNAL(valueChanged( double )), deg, SLOT(setRadius( double )) );
    connect( deg, SIGNAL(radiusChanged( double )), SLOT( updateAngle()) );
    connect( deg, SIGNAL(angleChanged( double )), SLOT( updateAngle()) );
    connect( deg, SIGNAL(angleChanged( double )), SLOT( setSinThetaOut()) );
    connect( deg, SIGNAL(angleChanged( double )), SLOT( setCosThetaOut()) );
    connect( deg, SIGNAL(angleChanged( double )), SLOT( setTanThetaOut()) );
    connect( deg, SIGNAL(angleChanged( double )), SLOT( setCotThetaOut()) );
    connect( deg, SIGNAL(angleChanged( double )), SLOT( setSecThetaOut()) );
    connect( deg, SIGNAL(angleChanged( double )), SLOT( setCosecThetaOut()) );
    connect( showAxis,SIGNAL(toggled( bool )), SLOT(updateAngle()) );
    connect( showTickMarks, SIGNAL(toggled( bool )), SLOT(updateAngle()) );
    connect( showTickLabels, SIGNAL(toggled( bool )), SLOT(updateAngle()) );
    connect( showDescriptions, SIGNAL(toggled( bool )), SLOT(updateAngle()) );

    initObjects();
}

TrigView::~TrigView()
{}

void TrigView::paintEvent( QPaintEvent* )
{
    pw->update();
}

void TrigView::updateAngle()
{

    if ( showAxis->isChecked() )
    {
        pw->setShowCartAxis( true );
    }
    else
    {
        pw->setShowCartAxis( false );
    }

    if ( showTickMarks->isChecked() )
    {
        pw->setShowCartTickMarks( true );
        showTickLabels->setEnabled ( true );
    }
    else
    {
        pw->setShowCartTickMarks( false );
        showTickLabels->setEnabled ( false );
    }

    if ( showTickLabels->isChecked() )
    {
        pw->setShowCartTickLabels( true );
    }
    else
    {
        pw->setShowCartTickLabels( false );
    }

    double limit = deg->radius();
    pw->setLimits( -limit, limit, -limit, limit );

    double radians = deg->angle() * M_PI / 180;
    double X_val = limit*cos(radians);
    double Y_val = limit*sin(radians);

    QString R_Length = QString::number( limit );

    QString X_Lenght = QString::number( limit*cos(radians) );

    QString Y_Lenght = QString::number( limit*sin(radians) );

    KPlotObject *r = pw->object( 0 );        //Radius
    r->point( 1 )->setX( X_val );
    r->point( 1 )->setY( Y_val );

    KPlotObject *x = pw->object( 1 );        //Adjacent
    x->point( 1 )->setX( X_val );

    KPlotObject *y = pw->object( 2 );        //Opposite
    y->point( 0 )->setX ( X_val );
    y->point( 1 )->setX ( X_val );
    y->point( 1 )->setY ( Y_val );

    KPlotObject *rl = pw->object( 3 );       //Radius Solution
    rl->point( 0 )->setX( (X_val)*0.70 );
    rl->point( 0 )->setY( (Y_val)*0.70 );
    rl->setName( R_Length );

    KPlotObject *xl = pw->object( 4 );       //Adjacent Solution
    xl->point( 0 )->setX( (X_val)/2 );
    xl->point( 0 )->setY( 0.0 );

    if ( deg->angle() == 90.0 || deg->angle() == 270.0 )
    {
        xl->setName( "0" );
    }
    else
    {
        xl->setName( X_Lenght );
    }

    KPlotObject *yl = pw->object( 5 );       //Opposite Solution
    yl->point( 0 )->setX( (X_val)*0.9 );
    yl->point( 0 )->setY( (Y_val)/2 );

    if ( deg->angle() == 180.0 || deg->angle() == 360.0 )
    {
        yl->setName( "0" );
    }
    else
    {
        yl->setName( Y_Lenght );
    }

    if ( showDescriptions->isChecked() )
    {
        KPlotObject *rd = pw->object( 6 );         //Opposite Lable
        rd->point( 0 )->setX( -(X_val)*0.7 );
        rd->point( 0 )->setY( -(Y_val)*0.7 );
        rd->setHidden( false );

        KPlotObject *xd = pw->object( 7 );         //Opposite Lable
        xd->point( 0 )->setX( -(X_val)*0.7 );
        xd->point( 0 )->setY( -(Y_val)*0.5 );
        xd->setHidden( false );

        KPlotObject *yd = pw->object( 8 );         //Opposite Lable
        yd->point( 0 )->setX( -(X_val)*0.7 );
        yd->point( 0 )->setY( -(Y_val)*0.3 );
        yd->setHidden( false );
    }
    else
    {
        pw->object( 6 )->setHidden(true);
        pw->object( 7 )->setHidden(true);
        pw->object( 8 )->setHidden(true);
    }
    update();
}

void TrigView::setSinThetaOut()
{
    double radians = deg->angle() * M_PI / 180;

    if ( deg->angle() == 180 || deg->angle() == 360)
    {
        SinThetaOut->setText( "0" );
    }
    else
    {
        QString qsSin = qsSin.number( sin(radians) );

        SinThetaOut->setText( qsSin );
    }
}

void TrigView::setCosThetaOut()
{
    double radians = deg->angle() * M_PI / 180;

    if ( deg->angle() == 90 || deg->angle() == 270)
    {
        CosThetaOut->setText( "0" );
    }
    else
    {
        QString qsCos = qsCos.number( cos(radians) );

        CosThetaOut->setText( qsCos );
    }
}

void TrigView::setTanThetaOut()
{
    double radians = deg->angle() * M_PI / 180;

    if ( deg->angle() == 90 || deg->angle() == 270 )
    {
        TanThetaOut->setText( "undefined" );
    }
    else if ( deg->angle() == 180 || deg->angle() == 360 )
    {
        TanThetaOut->setText( "0" );
    }
    else
    {
        QString qsTan = qsTan.number( tan(radians) );

        TanThetaOut->setText( qsTan );
    }
}

void TrigView::setCotThetaOut()
{
    double radians = deg->angle() * M_PI / 180;

    if ( deg->angle() == 0 || deg->angle() == 180 || deg->angle() == 360 )
    {
        CotThetaOut->setText( "undefined" );
    }

    else if ( deg->angle() == 90 || deg->angle() == 270 )
    {
        CotThetaOut->setText( "0" );
    }
    else
    {
        QString qsCot = qsCot.number( 1 / tan(radians) );

        CotThetaOut->setText( qsCot );
    }
}

void TrigView::setSecThetaOut()
{
    double radians = deg->angle() * M_PI / 180;

    if ( deg->angle() == 90 || deg->angle() == 270 )
    {
        SecThetaOut->setText( "undefined" );
    }
    else
    {
        QString qsSec = qsSec.number( 1 / cos(radians) );

        SecThetaOut->setText( qsSec );
    }
}

void TrigView::setCosecThetaOut()
{
    double radians = deg->angle() * M_PI / 180;

    if ( deg->angle() == 0 || deg->angle() == 180 || deg->angle() == 360 )
    {
        CosecThetaOut->setText( "undefined" );
    }
    else
    {
        QString qsCosec = qsCosec.number( 1 / sin(radians) );

        CosecThetaOut->setText( qsCosec );
    }
}

void TrigView::initObjects()
{
    KPlotObject *r_hypotenuse;
    KPlotObject *x_adjacent;
    KPlotObject *y_opposite;
    KPlotObject *r_lenght;
    KPlotObject *x_lenght;
    KPlotObject *y_lenght;
    KPlotObject *r_desc;
    KPlotObject *x_desc;
    KPlotObject *y_desc;

    double radians = deg->angle() * M_PI / 180;
    double X_val = 100*cos(radians);
    double Y_val = 100*sin(radians);

    r_hypotenuse = new KPlotObject( "R", "red", KPlotObject::POLYGON, 2, KPlotObject::SOLID );
    r_hypotenuse->addPoint( new DPoint( 0.0, 0.0 ) );
    r_hypotenuse->addPoint( new DPoint( X_val, Y_val ) );
    pw->addObject( r_hypotenuse );        //Draw R

    x_adjacent = new KPlotObject( "X", "red", KPlotObject::POLYGON, 2, KPlotObject::SOLID );
    x_adjacent->addPoint( new DPoint( 0.0, 0.0 ) );
    x_adjacent->addPoint( new DPoint( X_val, 0.0 ) );
    pw->addObject( x_adjacent );       //Draw X

    y_opposite = new KPlotObject( "Y", "red", KPlotObject::POLYGON, 2, KPlotObject::SOLID );
    y_opposite->addPoint( new DPoint( X_val, 0.0 ) );
    y_opposite->addPoint( new DPoint( X_val, Y_val ) );
    pw->addObject( y_opposite );       //Draw Y

    r_lenght = new KPlotObject( "r-lenth", "blue", KPlotObject::LABEL, 1, KPlotObject::SOLID );
    r_lenght->addPoint( new DPoint( (X_val)*0.65, (Y_val)*0.65 ));
    pw->addObject( r_lenght );

    x_lenght = new KPlotObject( "x-lenth", "green", KPlotObject::LABEL, 1, KPlotObject::SOLID );
    x_lenght->addPoint( new DPoint( (X_val)/2, 0.0 ));
    pw->addObject( x_lenght );

    y_lenght = new KPlotObject( "y-lenth", "yellow", KPlotObject::LABEL, 1, KPlotObject::SOLID );
    y_lenght->addPoint( new DPoint( (X_val)*0.9, (Y_val)/2 ));
    pw->addObject( y_lenght );

    r_desc = new KPlotObject( "Radius/Hypotenuse", "blue", KPlotObject::LABEL, 1, KPlotObject::SOLID );
    r_desc->addPoint( new DPoint( -(X_val)*0.7, -(Y_val)*0.7 ));
    pw->addObject( r_desc );

    x_desc = new KPlotObject( "X/Adjacent", "green", KPlotObject::LABEL, 1, KPlotObject::SOLID );
    x_desc->addPoint( new DPoint( -(X_val)*0.7, -(Y_val)*0.5 ));
    pw->addObject( x_desc );

    y_desc = new KPlotObject( "Y/Opposite", "yellow", KPlotObject::LABEL, 1, KPlotObject::SOLID );
    y_desc->addPoint( new DPoint( -(X_val)*0.7, -(Y_val)*0.3 ));
    pw->addObject( y_desc );
}

#include "trigview.moc"
