#include "NetworkReader.h"

/**
 * Constructor
 * @param networkFileName input xml file
 */
NetworkReader::NetworkReader(const char * xml) {
    ldsIndex = 0;
    loadLines(xml);
}

LOOP * NetworkReader::parseLoop(TiXmlElement * loopElem) {
        LOOP *loop = new LOOP;

        TiXmlElement *subLoopElem = loopElem->FirstChildElement();
        loop->loopID = atoi(subLoopElem->GetText());
        subLoopElem = subLoopElem->NextSiblingElement();
        loop->loop_loc = (char *) subLoopElem->GetText();
        subLoopElem = subLoopElem->NextSiblingElement();
        loop->vol = atoi(subLoopElem->GetText());
        subLoopElem = subLoopElem->NextSiblingElement();
        loop->occ = atof(subLoopElem->GetText());
        subLoopElem = subLoopElem->NextSiblingElement();
        loop->spd = atof(subLoopElem->GetText());
        
        return loop;
}

/**
 * Parses a station xml element into an "STATION"
 * 
 * @param stationElem the station xml element
 * @param the parent line
 * @return the new station
 */
STATION * NetworkReader::parseStation(TiXmlElement *stationElem, FEP_LINE *line) {
    STATION *station = new STATION;
    
    TiXmlElement *stationSubElem = stationElem->FirstChildElement();
    station->lds = atol(stationSubElem->GetText());
    cout << "Station: " << station->lds << endl;
    line->lds.push_back(station->lds);
    line->ldsIndex.push_back(ldsIndex++);
    stationSubElem = stationSubElem->NextSiblingElement();
    station->line_num = atoi(stationSubElem->GetText());
    stationSubElem = stationSubElem->NextSiblingElement();
    station->drop = atoi(stationSubElem->GetText());
    stationSubElem = stationSubElem->NextSiblingElement();
    stationSubElem = stationSubElem->NextSiblingElement(); // skip location
    stationSubElem = stationSubElem->NextSiblingElement(); // skip postmile
    stationSubElem = stationSubElem->NextSiblingElement(); // skip direction
    stationSubElem = stationSubElem->NextSiblingElement(); // skip freeway
    station->MlTotVol = atoi(stationSubElem->GetText());
    stationSubElem = stationSubElem->NextSiblingElement();
    station->OppTotVol = atoi(stationSubElem->GetText());

    station->pos = 0; // NOT SURE WHY WE NEED THIS?
    
    // Add loops to station
    TiXmlElement *loopElem = stationSubElem->NextSiblingElement()->FirstChildElement();
    for (loopElem; loopElem; loopElem = loopElem->NextSiblingElement()) {
        LOOP *loop = parseLoop(loopElem);
        station->loops.push_back(loop);
    }
    cout << "Number of Loops: " << station->loops.size() << endl;
    // Data pack ATMS message
    station->length = station->loops.size() * 2 + CONTROL_DATA_LEN;
    cout << station->loops.size() << endl;
    station->dataPack = DataPacker::packData(station);
    
    return station;
}

/**
 * Parses a "Line" xml element into an FEP_LINE
 * @param lineElem the xml element
 * @return FEP_LINE
 */
FEP_LINE * NetworkReader::parseLine(TiXmlElement * lineElem) {
    FEP_LINE *line = new FEP_LINE;

    TiXmlElement *lineSubElem = lineElem->FirstChildElement();
    line->lineNum = atoi(lineSubElem->GetText());
    cout << "Line: " << line->lineNum << endl;
    lineSubElem = lineSubElem->NextSiblingElement();
    line->count = atoi(lineSubElem->GetText());
    lineSubElem = lineSubElem->NextSiblingElement();
    line->schedule = atoi(lineSubElem->GetText());
    lineSubElem = lineSubElem->NextSiblingElement();
    line->lineInfo = atoi(lineSubElem->GetText());
    lineSubElem = lineSubElem->NextSiblingElement();
    line->systemKey = atol(lineSubElem->GetText());
    lineSubElem = lineSubElem->NextSiblingElement();
    line->globalSeq = atol(lineSubElem->GetText());
    lineSubElem = lineSubElem->NextSiblingElement();
    line->schedleSeq = atol(lineSubElem->GetText());

    TiXmlElement *stationsElem = lineSubElem->NextSiblingElement();
    TiXmlElement *stationElem = stationsElem->FirstChildElement();
    for (stationElem; stationElem; stationElem = stationElem->NextSiblingElement()) {
        stations.push_back(parseStation(stationElem, line));
    }
    return line;
}

/**
 * Loads FEPLines from a specified xml file
 * @param networkFileName the input xml file
 */
void NetworkReader::loadLines(const char * xml) {
    // Load network xml file
    TiXmlDocument doc;
    doc.Parse((const char*)xml, 0, TIXML_ENCODING_UTF8);

    // grab <Network> element
    TiXmlHandle hDoc(&doc);
    TiXmlElement *networkElem = hDoc.FirstChildElement().Element();

    // grab first <Line> element
    TiXmlElement *lineElem = networkElem->FirstChildElement();

    // iterate through each line element to create FEP_LINE list
    for (lineElem; lineElem; lineElem = lineElem->NextSiblingElement()) {
        lines.push_back(parseLine(lineElem));
    }
}

/**
 * Getter for lines
 * @return List of FEP_LINES
 */
vector<FEP_LINE*> NetworkReader::getLines() {

    return lines;
}

/**
 * Getter for stations
 * @return List of STATIONs
 */
vector<STATION*> NetworkReader::getStations() {

    return stations;
}

NetworkReader::~NetworkReader() {

}
