package com.yeejoin.amos.iec104.tcp.entity;

import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import io.netty.buffer.ByteBuf;


/**
 *信息体对象
 *
 */
public class InformationObject {
	
	private Log log = LogFactory.getLog(InformationObject.class);
	
    private int informationObjectAddress;
    private final InformationElement[][] informationElements;

    public InformationObject(int informationObjectAddress, InformationElement[][] informationElements) {
        this.informationObjectAddress = informationObjectAddress;
        this.informationElements = informationElements;
    }

    public InformationObject(ByteBuf is, int typeId, int numberOfSequenceElements)
            throws IOException {

        this.informationObjectAddress = (is.readByte() & 0xff) + ((is.readByte() & 0xff) << 8)
                + ((is.readByte() & 0xff) << 16);

        switch (typeId) {
            // 1 单点遥信
            case 1:
                informationElements = new InformationElement[numberOfSequenceElements][1];
                for (int i = 0; i < numberOfSequenceElements; i++) {
                    informationElements[i][0] = new IeSinglePointWithQuality(is);
                    log.debug("1 单点遥信: " + i + "--->" + informationElements[i][0].toString());
                }
                
                break;
            // 13 浮点型遥测
            case 13:
                informationElements = new InformationElement[numberOfSequenceElements][2];
                for (int i = 0; i < numberOfSequenceElements; i++) {
                    informationElements[i][0] = new IeShortFloat(is);
                    informationElements[i][1] = new IeQuality(is);
                    log.debug("13 浮点型遥测1: " + i + "--->" + informationElements[i][0].toString());
                    log.debug("13 浮点型遥测2: " + i + "--->" + informationElements[i][1].toString());
                }
                break;
            // 30 带 CP56Time2a 时标的单点信息
            case 30:
                informationElements = new InformationElement[numberOfSequenceElements][2];
                for (int i = 0; i < numberOfSequenceElements; i++) {
                    informationElements[i][0] = new IeSinglePointWithQuality(is);
                    informationElements[i][1] = new IeCP56Time2a(is);
                    log.debug("30 带 CP56Time2a 时标的单点信息 值: " + i + "--->" + informationElements[i][0].toString());
                    log.debug("30 带 CP56Time2a 时标的单点信息 时间: " + i + "--->" + ((IeCP56Time2a)informationElements[i][1]).getFormatDate("yyyy-MM-dd HH:mm:ss"));
                }
                break; 
           // 31 带 CP56Time2a 时标的双点信息
            case 31:
                informationElements = new InformationElement[numberOfSequenceElements][3];
                for (int i = 0; i < numberOfSequenceElements; i++) {
                    informationElements[i][0] = new IeSinglePointWithQuality(is);
                    informationElements[i][1] = new IeSinglePointWithQuality(is);
                    informationElements[i][2] = new IeCP56Time2a(is);
                    log.debug("31 带 CP56Time2a 时标的单点信息 值1: " + i + "--->" + informationElements[i][0].toString());
                    log.debug("31 带 CP56Time2a 时标的单点信息 值2: " + i + "--->" + informationElements[i][1].toString());
                    log.debug("31 带 CP56Time2a 时标的单点信息 时间: " + i + "--->" + ((IeCP56Time2a)informationElements[i][2]).getFormatDate("yyyy-MM-dd HH:mm:ss"));
                }
                break;                
            // 100 总召
            case 100:
                informationElements = new InformationElement[][] { { new IeQualifierOfInterrogation(is) } };
                log.debug("100 总召: " + informationElements[0][0].toString());
                break;
            case 103:
                informationElements = new InformationElement[][] { { new IeQualifierOfInterrogation(is) } };
                log.debug("103 总召: " + informationElements[0][0].toString());
                is.clear();
                break;
            default:
            	is.clear();
                throw new IOException(
                        "无法转换信息对象，由于类型标识未知: " + typeId);
        }
    }

    public int encode(byte[] buffer, int i) {
        int origi = i;

        buffer[i++] = (byte) informationObjectAddress;

        buffer[i++] = (byte) (informationObjectAddress >> 8);

        buffer[i++] = (byte) (informationObjectAddress >> 16);


        for (InformationElement[] informationElementCombination : informationElements) {
            for (InformationElement informationElement : informationElementCombination) {
                i += informationElement.encode(buffer, i);
            }
        }

        return i - origi;
    }

    public int getInformationObjectAddress() {
        return informationObjectAddress;
    }

    /**
     * 信息元素
     * 
     * @return 信息元素二维数组.
     */
    public InformationElement[][] getInformationElements() {
        return informationElements;
    }

    @Override
    public String toString() {

        StringBuilder builder = new StringBuilder("IOA: " + informationObjectAddress);

        if (informationElements.length > 1) {
            int i = 1;
            for (InformationElement[] informationElementSet : informationElements) {
                builder.append("\n信息体元素集 " + i + ":");
                for (InformationElement informationElement : informationElementSet) {
                    builder.append("\n");
                    builder.append(informationElement.toString());
                }
                i++;
            }
        }
        else {
            for (InformationElement[] informationElementSet : informationElements) {
                for (InformationElement informationElement : informationElementSet) {
                    builder.append("\n");
                    builder.append(informationElement.toString());
                }
            }
        }

        return builder.toString();

    }

}
