/******************************************************************************
 *
 * Project:  X-Plane fix.dat file reader
 * Purpose:  Implements OGRXPlaneFixReader class
 * Author:   Even Rouault, even dot rouault at mines dash paris dot org
 *
 ******************************************************************************
 * Copyright (c) 2008-2011, Even Rouault <even dot rouault at mines-paris dot org>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 ****************************************************************************/

#include "ogr_xplane_fix_reader.h"

CPL_CVSID("$Id: ogr_xplane_fix_reader.cpp 7e07230bbff24eb333608de4dbd460b7312839d0 2017-12-11 19:08:47Z Even Rouault $")

/************************************************************************/
/*                   OGRXPlaneCreateFixFileReader                       */
/************************************************************************/

OGRXPlaneReader* OGRXPlaneCreateFixFileReader( OGRXPlaneDataSource* poDataSource )
{
    OGRXPlaneReader* poReader = new OGRXPlaneFixReader(poDataSource);
    return poReader;
}

/************************************************************************/
/*                         OGRXPlaneFixReader()                         */
/************************************************************************/
OGRXPlaneFixReader::OGRXPlaneFixReader() :
    poFIXLayer(nullptr)
{}

/************************************************************************/
/*                          OGRXPlaneFixReader()                        */
/************************************************************************/

OGRXPlaneFixReader::OGRXPlaneFixReader( OGRXPlaneDataSource* poDataSource ) :
    poFIXLayer(new OGRXPlaneFIXLayer())
{
    poDataSource->RegisterLayer(poFIXLayer);
}

/************************************************************************/
/*                        CloneForLayer()                               */
/************************************************************************/

OGRXPlaneReader* OGRXPlaneFixReader::CloneForLayer(OGRXPlaneLayer* poLayer)
{
    OGRXPlaneFixReader* poReader = new OGRXPlaneFixReader();

    poReader->poInterestLayer = poLayer;

    SET_IF_INTEREST_LAYER(poFIXLayer);

    if (pszFilename)
    {
        poReader->pszFilename = CPLStrdup(pszFilename);
        poReader->fp = VSIFOpenL( pszFilename, "rt" );
    }

    return poReader;
}

/************************************************************************/
/*                         IsRecognizedVersion()                        */
/************************************************************************/

int OGRXPlaneFixReader::IsRecognizedVersion( const char* pszVersionString)
{
    return STARTS_WITH_CI(pszVersionString, "600 Version");
}

/************************************************************************/
/*                                Read()                                */
/************************************************************************/

void OGRXPlaneFixReader::Read()
{
    const char* pszLine = nullptr;
    while((pszLine = CPLReadLineL(fp)) != nullptr)
    {
        papszTokens = CSLTokenizeString(pszLine);
        nTokens = CSLCount(papszTokens);

        nLineNumber ++;

        if (nTokens == 1 && strcmp(papszTokens[0], "99") == 0)
        {
            CSLDestroy(papszTokens);
            papszTokens = nullptr;
            bEOF = true;
            return;
        }
        else if( nTokens == 0 || !assertMinCol(3) )
        {
            CSLDestroy(papszTokens);
            papszTokens = nullptr;
            continue;
        }

        ParseRecord();

        CSLDestroy(papszTokens);
        papszTokens = nullptr;

        if( poInterestLayer && !poInterestLayer->IsEmpty() )
            return;
    }

    papszTokens = nullptr;
    bEOF = true;
}

/************************************************************************/
/*                            ParseRecord()                             */
/************************************************************************/

void    OGRXPlaneFixReader::ParseRecord()
{
    double dfLat = 0.0;
    double dfLon = 0.0;
    CPLString osName;

    RET_IF_FAIL(readLatLon(&dfLat, &dfLon, 0));
    osName = readStringUntilEnd(2);

    if (poFIXLayer)
        poFIXLayer->AddFeature(osName, dfLat, dfLon);
}

/************************************************************************/
/*                           OGRXPlaneFIXLayer()                        */
/************************************************************************/

OGRXPlaneFIXLayer::OGRXPlaneFIXLayer() :
    OGRXPlaneLayer("FIX")
{
    poFeatureDefn->SetGeomType( wkbPoint );

    OGRFieldDefn oFieldName("fix_name", OFTString );
    oFieldName.SetPrecision(5);
    poFeatureDefn->AddFieldDefn( &oFieldName );
}

/************************************************************************/
/*                           AddFeature()                               */
/************************************************************************/

OGRFeature*
     OGRXPlaneFIXLayer::AddFeature(const char* pszFixName,
                                   double dfLat,
                                   double dfLon)
{
    int nCount = 0;
    OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
    poFeature->SetGeometryDirectly( new OGRPoint( dfLon, dfLat ) );
    poFeature->SetField( nCount++, pszFixName );

    RegisterFeature(poFeature);

    return poFeature;
}
