/***************************************************************************
                          factors.cpp  -  description
                             -------------------
    begin                : Fre Apr 12 2002
    copyright            : (C) 2002 by Birgit Schulz
    email                : B.Schulz@Superlehrer.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; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "factors.h"
#include "factors.moc"

#include <qspinbox.h>
#include <ktextbrowser.h>
#include <kpushbutton.h>
#include <klocale.h>
#include <kapplication.h>

#include <qlabel.h>
#include <qstring.h>

#include <math.h>


Factors::Factors(QWidget *parent, const char *name ) : FactorsD(parent,name)
{
    KTextBrowserResult->setText(" ");
    spinBox1->setValue( 0 );
    spinBox2->setValue( 0 );
    spinBox1->hide();
    spinBox2->hide();

    KPushButtonCalculate->hide();
    KPushButtonClear->hide();
    TextLabelFirstInfo->hide();
    TextLabelSecondInfo->hide();

    TextLabelInformation->setText(i18n("Choose a function from Icons below."));
}
Factors::~Factors()
{}

void Factors::slotClear()
{
    spinBox1-> setValue ( 0 );
    spinBox2-> setValue ( 0 );
    KTextBrowserResult->setText(" ");
}

void Factors::slotCalculate()
{
    switch (m_eSelected)
    {
    case FindFactors: //Find Factors
        {
            QString qsNumber = spinBox1->text();
            int iNumber = qsNumber.toInt();
            double iMax = sqrt(iNumber);
            int iFactorRest;
            QString qsFactor,qsFactorRest;
            QString qsResult = i18n("The factors of %1 are {1,").arg(qsNumber);
            QString qsResult2 = qsNumber + "}";

            for (int iFactor = 2; iFactor <= iMax ; ++iFactor)
            {
                if (iNumber % iFactor == 0)
                {
                    iFactorRest= iNumber/iFactor;
                    qsFactor = qsFactor.number(iFactor);
                    qsFactorRest = qsFactorRest.number(iFactorRest);
                    qsResult += qsFactor + ",";
                    qsResult2 = qsFactorRest + "," + qsResult2;
                }
                qsFactor = " ";
                qsFactorRest = " ";
            }
            qsResult.truncate(qsResult.length());
            qsResult += qsResult2;
            KTextBrowserResult->setText(qsResult);
            break;
        }

    case ProvePrime:  //Prove for Prime-Number
        {
            QString qsNumber = spinBox1->text();
            int iNumber = qsNumber.toInt();
            int iMax = iNumber;
            int iFactor2;
            QString qsFactor, qsFactor2;
            QString qsResult = "";
            bool bIsPrime = true;
            for (int iFactor = 2; iFactor < iMax ; ++iFactor)
            {
                if (iNumber % iFactor == 0)
                {
                    iFactor2 = iNumber = iNumber / iFactor;
                    qsFactor = qsFactor.number(iFactor);
                    qsFactor2 = qsFactor2.number(iFactor2);
                    qsResult = i18n("The number %1 is not a prime-number because\n").arg(qsNumber);
                    qsResult += qsNumber + " = " + qsFactor + " * " + qsFactor2;
                    bIsPrime = false;
                    break;
                }
            }
            if (bIsPrime)
            {
                qsResult = i18n("The number %1 is a prime-number").arg(qsNumber);
            }
            KTextBrowserResult->setText(qsResult);
            break;
        }

    case FindPrime: //Find Prime-Numbers
        {
            QString qsNumber1 = spinBox1->text();
            QString qsNumber2 = spinBox2->text();
            QString qsCount;
            int iNumber1 = spinBox1->value();
            int iNumber2 = spinBox2->value();
            int iCount = 0;
            QString qsResult = i18n("The prime numbers in the specified range are: ");
            bool i_IsPrime;
            for(int i = iNumber1; i <= iNumber2; i++)
            {
                if (i==2)
                    i_IsPrime = true;
                for (int iFactor = 2; iFactor < i; ++iFactor)
                {
                    if(i % iFactor == 0)
                    {
                        i_IsPrime = false;
                        break;
                    }
                    else
                        i_IsPrime = true;
                }
                if (i_IsPrime == true)
                {
                    iCount = iCount + 1;
                    qsNumber1 = qsNumber1.number(i);
                    qsResult += qsNumber1 + (", ");
                    qsCount = i18n("\nNumber of primes found: ") + qsCount.number(iCount);
                }
            }
            if ( iCount > 0 )
                KTextBrowserResult->setText(qsResult + qsCount);
            else
                KTextBrowserResult->setText(i18n("The are no prime numbers in the specified range."));

            break;
        }



    case FindHCF: //Find HCF
        {
            QString qsNumber1 = spinBox1->text();
            QString qsNumber2 = spinBox2->text();
            int iNumber1 = spinBox1->value();
            int iNumber2 = spinBox2->value();
            int iHCF = 1;
            QString qsHCF;
            while (iHCF != 0)
            {
                if (iNumber1 == iNumber2)
                {
                    iHCF = iNumber1;
                    break;
                }
                if(iNumber1 > iNumber2)
                {
                    iNumber1 = iNumber1 - iNumber2;
                }
                else
                {
                    iNumber2 = iNumber2 - iNumber1;
                }
            }
            qsHCF = qsHCF.number(iHCF);
            QString qsResult = i18n("The <b>H</b>ighest <b>C</b>ommon <b>F</b>actor of %1 and %2 is %3.").arg(qsNumber1,qsNumber2,qsHCF);
            KTextBrowserResult->setText(qsResult);
            break;
        }

    case FindLCM: //Find LCM
        {
            QString qsNumber1 = spinBox1->text();
            QString qsNumber2 = spinBox2->text();
            int iNumber1 = spinBox1->value();
            int iNumber2 = spinBox2->value();
            int iLCM = iNumber1*iNumber2;
            int iHCF = 1;
            QString qsLCM;
            while (iHCF != 0)
            {
                if (iNumber1 == iNumber2)
                {
                    iHCF = iNumber1;
                    break;
                }
                if(iNumber1 > iNumber2)
                {
                    iNumber1 = iNumber1 - iNumber2;
                }
                else
                {
                    iNumber2 = iNumber2 - iNumber1;
                }
            }
            iLCM /= iHCF;
            qsLCM = qsLCM.number(iLCM);
            QString qsResult = i18n("The <b>L</b>owest <b>C</b>ommon <b>M</b>ultiple of %1 and %2 is %3.").arg(qsNumber1,qsNumber2,qsLCM);
            KTextBrowserResult->setText(qsResult);
            break;
        }

    case Factorize:
        {
            QString qsNumber = spinBox1->text();
            int iNumber = spinBox1->value();
            int iMax = iNumber;
            bool bIsPrime = true;
            QString qsFactor;
            QString qsResult = i18n("The factorization of %1 is:\n").arg(qsNumber) + qsNumber + " = ";
            for (int iFactor = 2; iFactor < iMax ; ++iFactor)
            {
                if (iNumber % iFactor == 0)
                {
                    qsFactor = qsFactor.number(iFactor);
                    if ( bIsPrime )
                        qsResult += qsFactor;
                    else
                        qsResult += " * " + qsFactor;
                    bIsPrime = false;
                    qsFactor = " ";
                    iNumber = iNumber / iFactor;
                    iFactor -= 1;
                    if (iNumber == 1)
                        break;
                }
            }
            if (bIsPrime == true)
            {
                qsResult = i18n("It is impossible to find a factorization for %1 because it is a prime number.").arg(qsNumber);
            }
            KTextBrowserResult->setText(qsResult);
        }
    }
}


void Factors::slotShowFactorsFactorize()
{
    KTextBrowserResult->setText(" ");
    spinBox1->setValue( 0 );
    spinBox2->setValue( 0 );
    TextLabelFirstInfo->show();
    spinBox1->show();
    KPushButtonCalculate->show();
    KPushButtonClear->show();

    TextLabelInformation->setText(i18n("Factorize a given number"));
    TextLabelFirstInfo->setText(i18n("Number:"));
    TextLabelSecondInfo->hide();
    spinBox2->hide();
    m_eSelected = Factorize;
}

void Factors::slotShowFactorsFactors()
{
    KTextBrowserResult->setText(" ");
    spinBox1->setValue( 0 );
    spinBox2->setValue( 0 );
    TextLabelFirstInfo->show();
    spinBox1->show();
    KPushButtonCalculate->show();
    KPushButtonClear->show();

    TextLabelInformation->setText(i18n("Find all factors of a given number"));
    TextLabelFirstInfo->setText(i18n("Number:"));
    TextLabelSecondInfo->hide();
    spinBox2->hide();
    m_eSelected = FindFactors;
}

void Factors::slotShowFactorsFindHCF()
{
    KTextBrowserResult->setText(" ");
    spinBox1->setValue( 0 );
    spinBox2->setValue( 0 );
    spinBox1->show();
    spinBox2->show();
    TextLabelFirstInfo->show();
    TextLabelSecondInfo->show();
    KPushButtonCalculate->show();
    KPushButtonClear->show();

    TextLabelInformation->setText(i18n("Find the HCF of two numbers"));
    TextLabelFirstInfo->setText(i18n("First number:"));
    TextLabelSecondInfo->setText(i18n("Second number:"));
    m_eSelected = FindHCF;
}

void Factors::slotShowFactorsFindLCM()
{
    KTextBrowserResult->setText(" ");
    spinBox1->setValue( 0 );
    spinBox2->setValue( 0 );
    spinBox1->show();
    spinBox2->show();
    TextLabelFirstInfo->show();
    TextLabelSecondInfo->show();
    KPushButtonCalculate->show();
    KPushButtonClear->show();

    TextLabelInformation->setText(i18n("Find the LCM of two numbers"));
    TextLabelFirstInfo->setText(i18n("First number:"));
    TextLabelSecondInfo->setText(i18n("Second number:"));
    m_eSelected = FindLCM;
}

void Factors::slotShowFactorsProvePrime()
{
    KTextBrowserResult->setText(" ");
    spinBox1->setValue( 0 );
    spinBox2->setValue( 0 );
    TextLabelFirstInfo->show();
    spinBox1->show();
    KPushButtonCalculate->show();
    KPushButtonClear->show();

    TextLabelInformation->setText(i18n("Prove if given number is prime"));
    TextLabelFirstInfo->setText(i18n("Number:"));
    TextLabelSecondInfo->hide();
    spinBox2->hide();
    m_eSelected = ProvePrime;
}

void Factors::slotShowFactorsFindPrime()
{
    KTextBrowserResult->setText(" ");
    spinBox1->setValue( 0 );
    spinBox2->setValue( 0 );
    spinBox1->show();
    spinBox2->show();
    TextLabelFirstInfo->show();
    TextLabelSecondInfo->show();
    KPushButtonCalculate->show();
    KPushButtonClear->show();

    TextLabelInformation->setText(i18n("Find prime numbers in a range"));
    TextLabelFirstInfo->setText(i18n("Start number:"));
    TextLabelSecondInfo->setText(i18n("End number:"));
    m_eSelected = FindPrime;
}

