/***************************************************************************
                          lines.cpp  -  description
                             -------------------
    begin                : Son Apr 14 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 "lines.h"
#include "lines.moc"

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

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

Lines::Lines(QWidget *parent, const char *name ) : LinesD(parent,name)
    {
    }

Lines::~Lines()
    {
    }


void Lines::changeView(EFunctions eSelected)
{
    //Leeren der Boxen
    KTextBrowserResult->setText("");
    KRestrictedLineFirstInfo->setText("");
    KRestrictedLineSecondInfo->setText("");
    
    //2.Feld einschalten
    TextLabelSecondInfo->show();
    KRestrictedLineSecondInfo->show();

    switch (eSelected)
    {
        case OnePoint:
        {
            TextLabelInformation->setText(i18n("Find equation with given point and gradient"));
            TextLabelFirstInfo->setText(i18n("One point P:"));
            TextLabelSecondInfo->setText(i18n("Gradient m="));
            TextLabelSecondInfo->setEnabled(true);
            KRestrictedLineSecondInfo->setEnabled(true);
            KRestrictedLineFirstInfo->setValidChars("0123456789-.()|");
            KRestrictedLineSecondInfo->setValidChars("0123456789-.");
            KTextBrowserResult->setText("");

            m_iNumBoxNeed=2;
            m_eSelected = OnePoint;
            break;
        }

        case TwoPoints:
        {
            TextLabelInformation->setText(i18n("Find equation with two given points"));
            TextLabelFirstInfo->setText(i18n("First point P:"));
            TextLabelSecondInfo->setText(i18n("Second point Q:"));
            TextLabelSecondInfo->setEnabled(true);
            KRestrictedLineSecondInfo->setEnabled(true);
            KRestrictedLineFirstInfo->setValidChars("0123456789-.()|");
            KRestrictedLineSecondInfo->setValidChars("0123456789-.()|");
            KTextBrowserResult->setText("");

            m_iNumBoxNeed=2;
            m_eSelected = TwoPoints;
            break;
        }

        case AxisSection:
        {
            TextLabelInformation->setText(i18n("Find intersection with axis"));
            TextLabelFirstInfo->setText(i18n("First line-equation y="));
            TextLabelSecondInfo->show();
            KRestrictedLineSecondInfo->show();
            KRestrictedLineFirstInfo->setValidChars("0123456789-+.x*");
            KTextBrowserResult->setText("");

            m_iNumBoxNeed=1;
            m_eSelected = AxisSection;
            break;
        }

        case Section:
        {
            TextLabelInformation->setText(i18n("Find intersection-point of two lines"));
            TextLabelFirstInfo->setText(i18n("First line-equation y="));
            TextLabelSecondInfo->setText(i18n("Second line-equation y="));
            TextLabelSecondInfo->setEnabled(true);
            KRestrictedLineSecondInfo->setEnabled(true);
            KRestrictedLineFirstInfo->setValidChars("0123456789-+.x*");
            KRestrictedLineSecondInfo->setValidChars("0123456789-+.x*");
            KTextBrowserResult->setText("");

            m_iNumBoxNeed=2;
            m_eSelected = Section;
            break;
        }
    }
}


void Lines::slotCalculate()
{
    switch (m_eSelected)
    {
    case TwoPoints: //2 Punkte
        {
            double x1, y1, x2, y2;
            QString qsResult, qsX1, qsY1, qsX2, qsY2, qsB, qsM, qsEquation;

            int iPoint1 = sscanf(KRestrictedLineFirstInfo->text().utf8(), "( %lf | %lf )", &x1, &y1);
            int iPoint2 = sscanf(KRestrictedLineSecondInfo->text().utf8(), "( %lf | %lf )", &x2, &y2);
            if (iPoint1 + iPoint2 == 4)
            {
                qsX1 = qsX1.arg(x1);
                bool bSucess;
                double m = Steigung(x1, x2, y1, y2, bSucess);
                if (bSucess == false)
                {
                    qsResult = i18n("The line, going through the given points, is vertical.\n");
                    qsResult += i18n("So it is not a function and every point on this line has the property<p>x = ") + qsX1;
                    KTextBrowserResult->setText(qsResult);
                }
                else
                {
                    double b = Achsenabschnitt(m, x1, y1);
                    qsM = qsM.arg(m);
                    qsB = qsB.arg(b);
                    qsResult = i18n("The equation of the line going through the given points is:<p>");
                    if ( b == 0)
                    {
                        qsEquation = "y=" + qsM + "*x";
                        qsEquation = qsEquation.simplifyWhiteSpace();
                    }
                    else if (b > 0)
                    {
                        qsEquation = "y=" + qsM + "*x+" + qsB;
                        qsEquation = qsEquation.simplifyWhiteSpace();
                    }
                    else
                    {
                        qsEquation = "y=" + qsM + "*x" + qsB;
                        qsEquation = qsEquation.simplifyWhiteSpace();
                    }

                KTextBrowserResult->setText(qsResult + qsEquation);
                }
            }
            else
            {
                KTextBrowserResult->setText(i18n("<font color=red size=+1><b>Incorrect format!</b></font> <p> Enter points like <b><i>(x<sub>1</sub>|x<sub>2</sub>)</i></b>"));
            }

        break;
        }

        case OnePoint: //1 Punkt und Steigung
        {
            double x1, y1, m;
            QString qsResult, qsX1, qsY1, qsB, qsM, qsEquation;
            int iPoint1 = sscanf(KRestrictedLineFirstInfo->text().utf8(), "( %lf | %lf )", &x1, &y1);
            if (iPoint1 == 2)
            {
                qsM = KRestrictedLineSecondInfo->text();
                m = qsM.toDouble();
                double b = Achsenabschnitt(m, x1, y1);
                qsB = qsB.arg(b);
                qsResult = i18n("The line, with the given rising which going through the given point , has got the equation:\n\n");
                if ( b == 0)
                {
                    qsEquation += "y = " + qsM + " * x ";
                    qsEquation = qsEquation.simplifyWhiteSpace();
                }
                else if (b > 0)
                {
                    qsEquation += "y = " + qsM + " * x + " + qsB;
                    qsEquation = qsEquation.simplifyWhiteSpace();
                }
                else
                {
                    qsEquation += "y = " + qsM + "* x " + qsB;
                    qsEquation = qsEquation.simplifyWhiteSpace();
                }
            KTextBrowserResult->setText(qsResult + qsEquation);
            }
            else
            {
                KTextBrowserResult->setText(i18n("<font color=red size=+1><b>Incorrect format!</b></font> <p> Enter points like <b><i>(x<sub>1</sub>|x<sub>2</sub>)</i></b>"));
            }
        break;
        }

        case AxisSection: //Schnittpunkt mit Achsen
        {
            double m, b, xs, ys;
            QString qsResult, qsEquation, qsXs, qsYs;
            int iEquation1 = sscanf(KRestrictedLineFirstInfo->text().utf8(), " %lf *x %lf )", &m, &b);
            if (iEquation1 == 2)
            {
                if (m == 0)
                {
                    qsYs = qsYs.arg(ys);
                    qsResult = i18n("The line with the given equation is parallel to the x-axis, so it does not intersect it.<br>");
                    qsResult += i18n("The y-axis is intersected at <p>S( 0 | ") + qsYs + " ).";
                }
                else
                {
                    ys = b;
                    xs = (-1.0)*b/m;
                    qsXs = qsXs.arg(xs);
                    qsYs = qsYs.arg(ys);
                    qsResult = i18n("The given line crosses the <b>x-axis</b> at<br>");
                    qsResult += " S<sub>x</sub>( " + qsXs + i18n(" | 0 ) and the <b>y-axis</b> at \n");
                    qsResult += " S<sub>y</sub>( 0 | " + qsYs + " ).";
                }

            }
            else
            {
                qsResult=i18n("<font color=red size=+1><b>Incorrect format!</b></font> <p>Enter equation as <b><i>m*x+b</i></b> using numbers for m and b. <br>So for b equal to 0 and m equal to 1, enter the equation as: <b><i>1*x+0</i></b>, and not: <b><i>x</i></b>.");
            }
            KTextBrowserResult->setText(qsResult);
        break;
        }

        case Section: //Schnittpunkt von zwei geraden
        {
            double m1, b1, m2, b2, xs, ys;
            QString qsResult, qsEquation, qsXs, qsYs;
            int iEquation1 = sscanf(KRestrictedLineFirstInfo->text().utf8(), " %lf *x %lf )", &m1, &b1);
            int iEquation2 = sscanf(KRestrictedLineSecondInfo->text().utf8(), " %lf *x %lf )", &m2, &b2);
            if (iEquation1 + iEquation2 == 4)
            {
                if ((m1 - m2) == 0)
                {
                    if ((b1 - b2) == 0)
                    {
                        qsResult = i18n("The two given lines are identical, so there is an infinite number of intersecting points.");
                    }
                    else
                    {
                        qsResult = i18n("The two given lines are parallel, so there are no intersecting points.");
                    }
                }
                else
                {
                    xs = (b2 - b1)/(m1 - m2);
                    ys = m1*xs + b1;
                    qsXs = qsXs.arg(xs);
                    qsYs = qsYs.arg(ys);
                    qsResult = i18n("The point of intersection of the two given lines is<p>S( ") + qsXs + " | " + qsYs + " ).";
                    qsResult = qsResult.simplifyWhiteSpace();
                }
            }
            else
            {
                qsResult=i18n("<font color=red size=+1><b>Incorrect format!</b></font> <p>Enter equation like <b><i>m*x+b</i></b> and use numbers for m and b. <br>Even 0 as addend or 1 as factor should be used at first, e.g. <b><i>1*x+0</i></b> instead of <b><i>x</i></b>");
            }
            KTextBrowserResult->setText(qsResult);
            break;
        }
    }
}



void Lines::slotClear()
{
    KTextBrowserResult->setText("");
    KRestrictedLineFirstInfo->setText("");
    KRestrictedLineSecondInfo->setText("");
    KPushButtonCalculate->setEnabled(false); 
    KPushButtonClear->setEnabled(false); 
}

void Lines::slotCheckBoxes(const QString &qsText)
{
    if (m_iNumBoxNeed == 1)
    {
        if (qsText == "")
        {
            KPushButtonCalculate->setEnabled(false); 
            KPushButtonClear->setEnabled(false); 
        }  
        else 
        {
            KPushButtonCalculate->setEnabled(true); 
            KPushButtonClear->setEnabled(true); 
        }
    }
    else
    {
         if (qsText == "")
        {
            KPushButtonCalculate->setEnabled(false); 
            KPushButtonClear->setEnabled(false); 
        }  
        else if ((KRestrictedLineFirstInfo->text() == "") || (KRestrictedLineSecondInfo->text() == "")) 
        {
            KPushButtonCalculate->setEnabled(false); 
            KPushButtonClear->setEnabled(false); 
        }
        else
        {
            KPushButtonCalculate->setEnabled(true); 
            KPushButtonClear->setEnabled(true); 
        }
    }

}

double Lines::Steigung(double x1, double x2, double y1, double y2, bool &bSucess)
{
    if ((x1 - x2) == 0)
    {
        bSucess = false;
        return 0;
    }
    else
    {
        bSucess = true;
        double m = (y1 - y2)/(x1 - x2);
        return m;
    }
}

double Lines::Achsenabschnitt(double m, double x1, double y1)
{
    double b = y1 - m*x1;
    return b;
}
