#!/usr/bin/env python
#**********************************************************
*******************
# $Id$
#
# Project:  OpenGIS Simple Features Reference Implementation
# Purpose:  Python port of a simple client for viewing OGR driver data.
# Author:   Even Rou
ault, <even dot rouault at mines dash paris dot org>
#
# Port from ogrinfo.cpp whose author is Frank Warmerdam
#
#*****************************************************************************
# Copyright (c) 2010-2013, Even Rouault <even dot rouault at mines-paris dot org>
# Copyright (c) 1999, Frank Warmerdam
#
# 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.
#***************************************************************************/

# Note : this is the most direct port of ogrinfo.cpp possible
# It could be made much more Python'ish !

import sys

from osgeo import gdal
from osgeo import ogr

bReadOnly = False
bVerbose = True
bSummaryOnly = False
nFetchFID = ogr.NullFID
papszOptions = None

def EQUAL(a, b):
    return a.lower() == b.lower()

#**********************************************************************
#                                main()
#**********************************************************************

def main(argv = None):

    global bReadOnly
    global bVerbose
    global bSummaryOnly
    global nFetchFID
    global papszOptions
    layerlist=[]
    pszWHERE = None
    pszDataSource = None
    papszLayers = None
    poSpatialFilter = None
    nRepeatCount = 1
    bAllLayers = False
    pszSQLStatement = None
    pszDialect = None
    options = {}
    pszGeomField = None

    if argv is None:
        argv = sys.argv

    argv = ogr.GeneralCmdLineProcessor( argv )

# --------------------------------------------------------------------
#      Processing command line arguments.
# --------------------------------------------------------------------
    if argv is None:
        return 1

    nArgc = len(argv)

    iArg = 1
    while iArg < nArgc:

        if EQUAL(argv[iArg],"--utility_version"):
            print("%s is running against GDAL %s" %
                   (argv[0], gdal.VersionInfo("RELEASE_NAME")))
            return 0

        elif EQUAL(argv[iArg],"-ro"):
            bReadOnly = True
        elif EQUAL(argv[iArg],"-q") or EQUAL(argv[iArg],"-quiet"):
            bVerbose = False
        elif EQUAL(argv[iArg],"-fid") and iArg < nArgc-1:
            iArg = iArg + 1
            nFetchFID = int(argv[iArg])
        elif EQUAL(argv[iArg],"-spat") and iArg + 4 < nArgc:
            oRing = ogr.Geometry(ogr.wkbLinearRing)

            oRing.AddPoint( float(argv[iArg+1]), float(argv[iArg+2]) )
            oRing.AddPoint( float(argv[iArg+1]), float(argv[iArg+4]) )
            oRing.AddPoint( float(argv[iArg+3]), float(argv[iArg+4]) )
            oRing.AddPoint( float(argv[iArg+3]), float(argv[iArg+2]) )
            oRing.AddPoint( float(argv[iArg+1]), float(argv[iArg+2]) )

            poSpatialFilter = ogr.Geometry(ogr.wkbPolygon)
            poSpatialFilter.AddGeometry(oRing)
            iArg = iArg + 4

        elif EQUAL(argv[iArg],"-geomfield") and iArg < nArgc-1:
            iArg = iArg + 1
            pszGeomField = argv[iArg]

        elif EQUAL(argv[iArg],"-where") and iArg < nArgc-1:
            iArg = iArg + 1
            pszWHERE = argv[iArg]

        elif EQUAL(argv[iArg],"-sql") and iArg < nArgc-1:
            iArg = iArg + 1
            pszSQLStatement = argv[iArg]

        elif EQUAL(argv[iArg],"-dialect") and iArg < nArgc-1:
            iArg = iArg + 1
            pszDialect = argv[iArg]

        elif EQUAL(argv[iArg],"-rc") and iArg < nArgc-1:
            iArg = iArg + 1
            nRepeatCount = int(argv[iArg])

        elif EQUAL(argv[iArg],"-al"):
            bAllLayers = True

        elif EQUAL(argv[iArg],"-so") or EQUAL(argv[iArg],"-summary"):
            bSummaryOnly = True

        elif len(argv[iArg]) > 8 and EQUAL(argv[iArg][0:8],"-fields="):
            options['DISPLAY_FIELDS'] = argv[iArg][7:len(argv[iArg])]

        elif len(argv[iArg]) > 6 and EQUAL(argv[iArg][0:6],"-geom="):
            options['DISPLAY_GEOMETRY'] = argv[iArg][6:len(argv[iArg])]

        elif argv[iArg][0] == '-':
            return Usage()

        elif pszDataSource is None:
            pszDataSource = argv[iArg]
        else:
            if papszLayers is None:
                papszLayers = []
            papszLayers.append( argv[iArg] )
            bAllLayers = False

        iArg = iArg + 1

    if pszDataSource is None:
        return Usage()

# --------------------------------------------------------------------
#      Open data source.
# --------------------------------------------------------------------
    poDS = None
    poDriver = None

    poDS = ogr.Open( pszDataSource, not bReadOnly )
    if poDS is None and not bReadOnly:
        poDS = ogr.Open( pszDataSource, False )
        if poDS is not None and bVerbose:
            #print( "Had to open data source read-only." )
            bReadOnly = True

# --------------------------------------------------------------------
#      Report failure.
# --------------------------------------------------------------------
    if poDS is None:
        print( "FAILURE:\n"
                "Unable to open datasource `%s' with the following drivers." % pszDataSource )

        for iDriver in range(ogr.GetDriverCount()):
            print( "  -> %s" % ogr.GetDriver(iDriver).GetName() )

        return 1

    poDriver = poDS.GetDriver()

# --------------------------------------------------------------------
#      Some information messages.
# --------------------------------------------------------------------
    if bVerbose:
        print( "INFO: Open of `%s'\n"
                "      using driver `%s' successful." % (pszDataSource, poDriver.GetName()) )

    poDS_Name = poDS.GetName()
    if str(type(pszDataSource)) == "<type 'unicode'>" and str(type(poDS_Name)) == "<type 'str'>":
        poDS_Name = poDS_Name.decode("utf8")
    if bVerbose and pszDataSource != poDS_Name:
        print( "INFO: Internal data source name `%s'\n"
                "      different from user name `%s'." % (poDS_Name, pszDataSource ))

# --------------------------------------------------------------------
#      Special case for -sql clause.  No source layers required.
# --------------------------------------------------------------------
    if pszSQLStatement is not None:
        poResultSet = None

        nRepeatCount = 0  #// skip layer reporting.

        if papszLayers is not None:
            print( "layer names ignored in combination with -sql." )

        if pszGeomField is None:
            poResultSet = poDS.ExecuteSQL( pszSQLStatement, poSpatialFilter,
                                            pszDialect )
        else:
            poResultSet = poDS.ExecuteSQL( pszSQLStatement, None, pszDialect )

        if poResultSet is not None:
            if pszWHERE is not None:
                if poResultSet.SetAttributeFilter( pszWHERE ) != 0:
                    print("FAILURE: SetAttributeFilter(%s) failed." % pszWHERE)
                    return 1

            if pszGeomField is not None:
                ReportOnLay