
#include "ImportNastran.h"
#include "RTMSimulator.h"
#include "Import.h"

#include <QApplication>
#include <QDesktopWidget>
#include <QString>
#include <QWidget>
#include <QHBoxLayout>
#include <QLabel>
#include <QFile>
#include <QStringList>
#include <QTextStream>

#include <cmath>
#include <iostream>
#include <list>

/**
 * Creates a temporary import object to read in a Nastran file.
 * @param pFile File to read in.
 * @param pSimulator Pointer to the RTMSimulator object to read into.
 */
ImportNastran::ImportNastran(QFile* pFile, RTMSimulator* pSimulator):
        ImportFormat(pSimulator),
        m_numberOfNodes(0),
        m_numberOfElements(0)
{
    read(pFile);
}

/**
 * Creates a temporary import object to read in a Nastran file.
 * @param strFile Fully qualified path to a file to read in.
 * @param pSimulator Pointer to the RTMSimulator object to read into.
 */
ImportNastran::ImportNastran(QString strFile, RTMSimulator* pSimulator):
        ImportFormat(pSimulator),
        m_numberOfNodes(0),
        m_numberOfElements(0)
{
    QFile* pFile = new QFile(strFile);
    read(pFile);
    pFile->close();
}

/**
 * Reads in data from the Nastran file specified by the parameter.
 * @pFile Pointer to the file to read from
 */
void ImportNastran::read(QFile* pFile)
{
    InfoBox infoBox("reading Size Information...");
    qApp->processEvents();

    infoBox.setText("importing Nodes...");
    qApp->processEvents();
    if(!importNodes(pFile))
    {
        //here we should display an error message
        infoBox.hide();
        return;
    }

    infoBox.setText("importing Connections...");
    qApp->processEvents();
    if(!importConnections(pFile))
    {
        //here we should display an error message
        infoBox.hide();
        return;
    }
    infoBox.hide();
}

/**
 * Reads in the nodes from a nastran file
 * @param pFile Pointer to the file to read from
 */
bool ImportNastran::importNodes(QFile* pFile)
{
    while (!pFile->atEnd())
    {
        QString line = pFile->readLine();
        if(line.startsWith("GRID*",Qt::CaseInsensitive))
        {
            QString line2 = pFile->readLine();
            if(line2.startsWith("*"))
            {
                line.append(line2);
                line.remove(QChar('*'));
                line = line.trimmed();
                line.chop(1);
                QTextStream istream(&line);
                QString gridMark;
                int nodeId;
                double x,y,z;
                istream >> gridMark >> nodeId >> x >> y >> z;
                m_pSimulator->addNode(nodeId,x,y,z);
            }
        }
    }

    pFile->reset();
    return true;
}

/**
 * Reads in the connections from a Nastran file.
 * @param pFile Pointer to the file to read from
 */
bool ImportNastran::importConnections(QFile* pFile)
{
    QString line;
    while(!pFile->atEnd())
    {
        line = pFile->readLine().trimmed();
        if(line.startsWith("CTETRA"))
        {
            QString line2 = pFile->readLine();
            line.append(line2);
            line = line.trimmed();
            QTextStream istream(&line);
            QString tetraMarker;
            int tetraId, unknown;
            istream >> tetraMarker >> tetraId >> unknown;
            int a,b,c,d;
            istream >> a >> b >> c >> d;
            std::list<int> neighbors;
            neighbors.push_back(a);
            neighbors.push_back(b);
            neighbors.push_back(c);
            neighbors.push_back(d);
            makeDirectNeighbors(&neighbors);
            addTetraeder(&neighbors);

        }
        else if(line.startsWith("CTRIA3") || line.startsWith("CQUAD4") )
        {
            line.remove(0,6);
            QTextStream istream(&line);

            int connectivityId, unknown, connection;
            std::list<int> connectionList;
            istream >> connectivityId >> unknown;
            while(!istream.atEnd())
            {
                istream >> connection;
                connectionList.push_back(connection);
            }

            if(connectionList.size() >= 2)
            {
                for(std::list<int>::const_iterator it = connectionList.begin(); it != connectionList.end(); it++)
                {
                    std::list<int>::const_iterator itNode2 = it;
                    itNode2++;
                    if(itNode2 == connectionList.end())
                        itNode2 = connectionList.begin();

                    m_pSimulator->setDirectNeighbor(*it,*itNode2);
                    m_pSimulator->setDirectNeighbor(*itNode2,*it);
                }
            }
        }
    }
    pFile->reset();
    return true;
}


