/*
 */
package com.teltonikaServer.protocol;

import java.util.logging.Level;

import com.teltonikaServer.lib.Utils;
import com.teltonikaServer.network.TCPServer;

/**
 *
 * @author Americo
 */
public class IoElementsSection extends CodecIoSection {

    private int offset;
    protected long ignitionCounter = -1;
    protected int inputs = 0;
    protected int outputs = 0;

    public IoElementsSection() {

    }

    public int getOffset() {
        return this.offset;
    }

    public boolean parse(byte ioElementArray[]) throws ParseException {
        this.IO_id = (int) Utils.getLongFromMessageArray(ioElementArray, 0, 2);
        int totalElements = (int) Utils.getLongFromMessageArray(ioElementArray, 2, 2);

        // 1 Byte
        int OneByteElementsCount = (int) Utils.getLongFromMessageArray(ioElementArray, 4, 2);
        this.offset = 6;

        // Obtener los elementos de 1 Byte
        for (int i = 0; i < OneByteElementsCount; i++) {
            int id = (int) Utils.getLongFromMessageArray(ioElementArray, offset, 2);
            this.offset += 2;
            String value = Utils.getHexString(Utils.getSubArray(ioElementArray, offset, 1)); // new
                                                                                             // String(Utils.getSubArray(ioElementArray,
                                                                                             // offset, 1));
            this.offset++;
            this.ioComponents.add(new IO_Component(id, value));

            // SetInputs
            if (id == Teltonika.INPUT1) {
                if (Integer.parseInt(value) == 1)
                    this.inputs = this.inputs | 1;
            }
            if (id == Teltonika.INPUT2) {
                if (Integer.parseInt(value) == 1)
                    this.inputs = this.inputs | 2;
            }
            if (id == Teltonika.INPUT3) {
                if (Integer.parseInt(value) == 1)
                    this.inputs = this.inputs | 4;
            }

            // Set outputs
            if (id == Teltonika.OUTPUT1) {
                if (Integer.parseInt(value) == 1)
                    this.outputs = this.inputs | 1;
            }
            if (id == Teltonika.OUTPUT2) {
                if (Integer.parseInt(value) == 1)
                    this.outputs = this.inputs | 2;
            }
            if (id == Teltonika.OUTPUT3) {
                if (Integer.parseInt(value) == 1)
                    this.outputs = this.inputs | 4;
            }

        }

        // 2 Byte
        int twoByteElementsCount = (int) Utils.getLongFromMessageArray(ioElementArray, offset, 2);
        offset += 2;

        for (int i = 0; i < twoByteElementsCount; i++) {
            int id = (int) Utils.getLongFromMessageArray(ioElementArray, offset, 2);
            this.offset += 2;
            String value = Utils.getHexString(Utils.getSubArray(ioElementArray, offset, 2)); // new
                                                                                             // String(Utils.getSubArray(ioElementArray,
                                                                                             // offset, 2));
            this.offset += 2;
            this.ioComponents.add(new IO_Component(id, value));

            if (id == Teltonika.AD1) {
                this.ad1 = Integer.parseInt(value, 16);
            }
        }

        // 4 Byte
        int fourByteElementsCount = (int) Utils.getLongFromMessageArray(ioElementArray, offset, 2);
        this.offset += 2;

        for (int i = 0; i < fourByteElementsCount; i++) {
            int id = (int) Utils.getLongFromMessageArray(ioElementArray, offset, 2);
            this.offset += 2;
            String value = Utils.getHexString(Utils.getSubArray(ioElementArray, offset, 4)); // new
                                                                                             // String(Utils.getSubArray(ioElementArray,
                                                                                             // offset, 4));
            this.offset += 4;
            this.ioComponents.add(new IO_Component(id, value));
            if (id == Teltonika.IGNITION_COUNTER) {
                this.ignitionCounter = Long.valueOf(value, 16);
            }
        }

        // 8 Byte
        int eightByteElementsCount = (int) Utils.getLongFromMessageArray(ioElementArray, offset, 2);
        this.offset += 2;

        for (int i = 0; i < eightByteElementsCount; i++) {
            int id = (int) Utils.getLongFromMessageArray(ioElementArray, offset, 2);
            this.offset += 2;
            String value = Utils.getHexString(Utils.getSubArray(ioElementArray, offset, 8)); // new
                                                                                             // String(Utils.getSubArray(ioElementArray,
                                                                                             // offset, 8));
            this.offset += 8;
            this.ioComponents.add(new IO_Component(id, value));
        }

        // Variable length elements
        int varLenElementsCount = (int) Utils.getLongFromMessageArray(ioElementArray, offset, 2);
        this.offset += 2;

        for (int i = 0; i < varLenElementsCount; i++) {
            int id = (int) Utils.getLongFromMessageArray(ioElementArray, offset, 2);
            this.offset += 2;
            int valueLength = (int) Utils.getLongFromMessageArray(ioElementArray, offset, 2);
            this.offset += 2;
            String value = Utils.getHexString(Utils.getSubArray(ioElementArray, offset, valueLength)); // new
                                                                                                       // String(Utils.getSubArray(ioElementArray,
                                                                                                       // offset,
                                                                                                       // valueLength));
            this.offset += valueLength;
            this.ioComponents.add(new IO_Component(id, value));
        }

        if (OneByteElementsCount + twoByteElementsCount + fourByteElementsCount + eightByteElementsCount
                + varLenElementsCount != totalElements) {
            throw new ParseException("Error de parsing en IO Elements");
        }

        if ((TCPServer.VERBOSITY & TCPServer.VERB_FINE) > 0) {
            for (IO_Component c : this.ioComponents) {

                TCPServer.serverLog.logEvent(Level.FINE, " IO " + c.getComponentId() + ", val " + c.getComponentValue());

            }
        }
        return true;
    }

    public IO_Component getNextComponent() {
        try {
            IO_Component component = this.componentsIterator.next();
            return component;
        } catch (Exception exception) {
            return null;
        }
    }

    public long getIgnitionCounter() {
        return this.ignitionCounter;
    }

    public int getInputs() {
        return this.inputs;
    }

    public int getOutputs() {
        return this.outputs;
    }

    public int getAd1() {
        return this.ad1;
    }

}
