package gov.nasa.worldwind.formats.rpf;

import gov.nasa.worldwind.formats.nitfs.*;
import gov.nasa.worldwind.*;

import java.util.*;
/*
Copyright (C) 2001, 2007 United States Government
as represented by the Administrator of the
National Aeronautics and Space Administration.
All Rights Reserved.
*/

/**
 * @author Lado Garakanidze
 * @version $Id: RpfFileIndexSection Apr 4, 2007 6:32:20 PM lado
 */
public class RpfFrameFileIndexSection
{
    // [ frame file index section subheader ]
    private String   highestSecurityClassification;
    private long     frameFileIndexTableOffset;
    private long     numOfFrameFileIndexRecords;
    private int      numOfPathnameRecords;
    private int      frameFileIndexRecordLength;

    // [ frame file index subsection ]

    //      [ frame file index table ]
    private ArrayList<RpfFrameFileIndexRecord> frameFileIndexTable = new ArrayList<RpfFrameFileIndexRecord>();
    //      [ pathname table ]
    // private ArrayList<String> pathnameTable = new ArrayList<String>();

    
    public String getHighestSecurityClassification()
    {
        return highestSecurityClassification;
    }

    public long getFrameFileIndexTableOffset()
    {
        return frameFileIndexTableOffset;
    }

    public long getNumOfFrameFileIndexRecords()
    {
        return numOfFrameFileIndexRecords;
    }

    public int getNumOfPathnameRecords()
    {
        return numOfPathnameRecords;
    }

    public int getFrameFileIndexRecordLength()
    {
        return frameFileIndexRecordLength;
    }

    public ArrayList<RpfFrameFileIndexRecord> getFrameFileIndexTable()
    {
        return frameFileIndexTable;
    }

//    public ArrayList<String> getPathnameTable()
//    {
//        return pathnameTable;
//    }

    public RpfFrameFileIndexSection(java.nio.ByteBuffer buffer)
    {
        // [ frame file index section subheader ]
        this.highestSecurityClassification = NitfsUtil.getString(buffer, 1);
        this.frameFileIndexTableOffset = NitfsUtil.getUInt(buffer);
        this.numOfFrameFileIndexRecords = NitfsUtil.getUInt(buffer);
        this.numOfPathnameRecords = NitfsUtil.getUShort(buffer);
        this.frameFileIndexRecordLength = NitfsUtil.getUShort(buffer);

        this.parseFrameFileIndexAndPathnameTables( buffer );
    }

    private void parseFrameFileIndexAndPathnameTables(java.nio.ByteBuffer buffer)
    {
        int theSectionOffset = buffer.position();
        Hashtable<Integer, String> pathnames = new Hashtable<Integer, String>();

        for(int i = 0 ; i < this.numOfFrameFileIndexRecords; i++)
            this.frameFileIndexTable.add(new RpfFrameFileIndexRecord(buffer));

        for(int i = 0 ; i < this.numOfPathnameRecords; i++)
        {
            int relOffset = buffer.position() - theSectionOffset;
            int len = NitfsUtil.getUShort(buffer);
            pathnames.put(relOffset, NitfsUtil.getString(buffer, len));
        }

        if(0 < this.frameFileIndexTable.size() && 0 < pathnames.size())
        { // update pathname field in every RpfFrameFileIndexRecord
            for (RpfFrameFileIndexRecord rec : this.frameFileIndexTable)
            {
                int offset = (int) rec.getPathnameRecordOffset();
                if (pathnames.containsKey(offset))
                    rec.setPathname(pathnames.get(offset));
                else
                    throw new NitfsRuntimeException("NitfsReader.CorrespondingPathnameWasNotFound");
            }
        }
    }

    public class RpfFrameFileIndexRecord
    {
        public int getBoundaryRectangleRecordNumber()
        {
            return boundaryRectangleRecordNumber;
        }

        public int getFrameLocationRowNumber()
        {
            return frameLocationRowNumber;
        }

        public int getFrameLocationColumnNumber()
        {
            return frameLocationColumnNumber;
        }

        public String getFrameFileName()
        {
            return frameFileName;
        }

        public String getGeoLocation()
        {
            return geoLocation;
        }

        public String getSecurityClass()
        {
            return securityClass;
        }

        public String getSecurityCountryCode()
        {
            return securityCountryCode;
        }

        public String getSecurityReleaseMark()
        {
            return securityReleaseMark;
        }

        public long getPathnameRecordOffset()
        {
            return pathnameRecordOffset;
        }

        public String getPathname()
        {
            return pathname;
        }

        public void setPathname(String pathname)
        {
            this.pathname = pathname;
        }
        
        private int      boundaryRectangleRecordNumber;
        private int      frameLocationRowNumber;
        private int      frameLocationColumnNumber;
        private long     pathnameRecordOffset;
        private String   frameFileName;
        private String   geoLocation;
        private String   securityClass;
        private String   securityCountryCode;
        private String   securityReleaseMark;
        private String   pathname;   // this field is not part of the NITFS spec


        public RpfFrameFileIndexRecord(java.nio.ByteBuffer buffer)
        {
            this.boundaryRectangleRecordNumber = NitfsUtil.getUShort(buffer);
            this.frameLocationRowNumber = NitfsUtil.getUShort(buffer);
            this.frameLocationColumnNumber = NitfsUtil.getUShort(buffer);
            this.pathnameRecordOffset = NitfsUtil.getUInt(buffer);
            this.frameFileName = NitfsUtil.getString(buffer, 12);
            this.geoLocation = NitfsUtil.getString(buffer, 6);
            this.securityClass = NitfsUtil.getString(buffer, 1);
            this.securityCountryCode = NitfsUtil.getString(buffer, 2);
            this.securityReleaseMark = NitfsUtil.getString(buffer, 2);
            this.pathname = StringUtil.EMPTY;
        }
    }
}
