/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package ipmreader;

/**
 *
 * @author Lisewski
 */
public class IPMReader {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {
        IPMInputStream is = new IPMInputStream("c:/GPS/FileWatcherServiceTestFiles1.5/T112-1000k.ipm");
//        var blockSize = 1012;
//        var blockChar = 0x00;

        while (!is.lastBlock) {
            byte[] ba = is.readNBytes(4);
//            System.out.println(Integer.toBinaryString(ba[0]));
//            System.out.println(Integer.toBinaryString(ba[1]));
//        System.out.println(String.format("%8s", Integer.toBinaryString(ba[2])).replace(' ', '0'));
//        System.out.println(String.format("%8s", Integer.toBinaryString(ba[3])).replace(' ', '0'));
//        System.out.println(Integer.toBinaryString(ba[3] & 0xFF));
//        System.out.println(new String(ba, "Windows-1252"));
            // format is 00LL bytes 0 and 1 should be 0
            var recordLength = 256 * (ba[2] & 0xFF) + (ba[3] & 0xFF);
            if (recordLength == 0) {
                break;
            }
//            System.out.println(recordLength);
            //ba = bais.readNBytes(recordLength);
//            ByteArrayInputStream bais = new ByteArrayInputStream(ba);
            var RecordBitmap = new Boolean[IpmSpecificationConstants.DataElementCount];
            var RecordDataElements = new String[IpmSpecificationConstants.DataElementCount];
            RecordBitmap[0] = true;

            var messageTypeIdBytes = is.readNBytes(4);
            var messsageTypeId = new String(messageTypeIdBytes, "Windows-1252");
//            System.out.format("Message Type : %s\n", messsageTypeId);
            for (var i = 0; i < IpmSpecificationConstants.DataElementCount; i++) {
                if (RecordBitmap[i]) {
                    StringBuilder sb = new StringBuilder();
                    var elementLength = GetDataElementLength(is, i);
                    ba = is.readNBytes(elementLength);
                    var elementFormat = IpmDataElements.DataElements[i].Format;
                    if (elementFormat == IpmSpecificationConstants.DataElementFormat.Binary || elementFormat == IpmSpecificationConstants.DataElementFormat.HexadecimalBinary) {
                            for (var j = 0; j < elementLength; j++) {
                                sb.append(String.format("%8s", Integer.toBinaryString(ba[j] & 0xFF)).replace(' ', '0'));
                            }
                            var binaryStringValue = sb.toString();
                        var isBitmap = IpmDataElements.DataElements[i].IsBitmap;
                       if (isBitmap) {
                            var bitmapStartIndex = IpmDataElements.DataElements[i].BitmapStartIndex;
                            for (var j = 0; j < binaryStringValue.length(); j++) {
                                var c = binaryStringValue.charAt(j);
                                RecordBitmap[j + bitmapStartIndex] = c == '1';
                            }
                        }
                        RecordDataElements[i] = sb.toString();

                    } else {
                        RecordDataElements[i] = new String(ba, "Windows-1252");
                    }
                }
            }
            for (var i = 0; i < RecordDataElements.length; i++) {
                if (RecordBitmap[i]) {
//                    System.out.format("%03d (%s): %s\n", i, IpmDataElements.DataElements[i].Name, RecordDataElements[i]);
                }
            }
        }
    }

    static int GetDataElementLength(IPMInputStream bais, int dataElementIndex) {
        var elementSize = IpmDataElements.DataElements[dataElementIndex].LengthData.LllSize;
        if (elementSize == 0) {
            return IpmDataElements.DataElements[dataElementIndex].LengthData.MaximumLength;
        }
        String s = "";
        try {
            var elementLengthBytes = bais.readNBytes(elementSize);
            s = new String(elementLengthBytes);
            return Integer.parseInt(s);
        } catch (Exception ex) {
            System.out.format("%03d: %s is not a number\n", dataElementIndex, s);
            return 4;
        }
    }
}
