package cz.vutbr.feec.packets.ttp;

import java.util.Vector;

import cz.vutbr.feec.packets.IPacket;
import cz.vutbr.feec.packets.PacketGenerateException;
import cz.vutbr.feec.packets.PacketParseException;
import cz.vutbr.feec.packets.PacketUtils;

import org.apache.commons.lang.builder.ToStringBuilder;

public class FTSGroupBlockFT implements IPacket {
	
	private int SFTST;
	private int length;
	private long feedbackTargetPort;
	private long feedbackTargerIP;
	
	private long groupSize;
	private int padding;
	private int priority;
	private int height;
	private long vectorFormat;
	
	
	private Vector<FTS_GB_LMidVectorGroup> groupList = new Vector<FTS_GB_LMidVectorGroup>();

	/**
	 * @param sftst definuje tzp subBloku pro FT_IPv4 = 1 pro LM_IPv4 = 3
	 * @param length definuje velikost subbloku
	 * @param port definuje port na kterem FT posloucha
	 * @param IPaddress definuje IP adresu FT
	 * @param groupSize definuje vleikost skupinz FT
	 * @param padding definuje vypln
	 * @param priority definuje prioritu
	 * @param height definuje uroven v kter se FT na chazi
	 * @param vecFormat definuje typ formatu vektoru
	 */
	public FTSGroupBlockFT (){
		
	};
	
	public FTSGroupBlockFT (int sftst, int length, long port, long IPaddress,
			long groupSize, int padding, int priority, int height, int vecFormat){
		setSFTST(sftst);
		setLength(length);
		setFeedbackTargetPort(port);
		setFeedbackTargerIP(IPaddress);
		setGroupSize(groupSize);
		setPadding(padding);
		setPriority(priority);
		setHeight(height);
		setVectorFormat(vecFormat);
		
		
	}
	public void addGroupBlock(FTS_GB_LMidVectorGroup group) {
		groupList.add(group);
	}

	public FTS_GB_LMidVectorGroup getGroupBlock(int index) {

		return groupList.get(index);
	}
	
	/* (non-Javadoc)
	 * @see cz.vutbr.feec.packets.IPacket#generate(byte[], int)
	 */

	public int generate(byte[] buffer, int offset)
			throws PacketGenerateException {
		assert PacketUtils.checkSize(getSFTST(), 8);
		assert PacketUtils.checkSize(getLength(), 8);
		assert PacketUtils.checkSize(getFeedbackTargetPort(), 16);
		assert PacketUtils.checkSize(getFeedbackTargerIP(), 32);
		
		assert PacketUtils.checkSize(getGroupSize(), 16);
		assert PacketUtils.checkSize(getPadding(), 1);
		assert PacketUtils.checkSize(getPriority(), 7);
		assert PacketUtils.checkSize(getHeight(), 3);
		assert PacketUtils.checkSize(getVectorFormat(), 5);
		
		PacketUtils.setOctet1(buffer, offset, getSFTST());
		PacketUtils.setOctet1(buffer, offset + 1, getLength());
		PacketUtils.setOctet2(buffer, offset + 2, getFeedbackTargetPort());
		PacketUtils.setOctet4(buffer, offset + 4, getFeedbackTargerIP());
		
		
		PacketUtils.setOctet2(buffer, offset + 8, getGroupSize());
		
		byte P_Prio = (byte) ((padding << 7) & 0x80 | priority & 0x7F);
		buffer[offset + 10] = P_Prio;
		
		byte Hei_VF = (byte) ((height << 5) & 0xE0 | vectorFormat & 0x1F);
		buffer[offset + 11] = Hei_VF;
			
		
		int len = 12; 			//  12 because there are 12*4 bites on at start of the group
		
		for (FTS_GB_LMidVectorGroup group : groupList) {
			len += group.generate(buffer, offset+len);
		}
		

		return len;
	}

	
	public int parse(byte[] buffer, int offset, int length)
			throws PacketParseException {
		
		setSFTST(PacketUtils.getOctet1(buffer, offset));
		setLength(PacketUtils.getOctet1(buffer, 1 + offset));
		setFeedbackTargetPort(PacketUtils.getOctet2(buffer, 2 + offset));
		setFeedbackTargerIP(PacketUtils.getOctet4(buffer, 4 + offset));
		
		setGroupSize(PacketUtils.getOctet2(buffer, 8+ offset));
		
		int P_Prio = PacketUtils.getOctet1(buffer, 10 + offset);
		setPadding((P_Prio & 0x80) >>7);
		setPriority(P_Prio & 0x7F);
		
		int Hei_VF = PacketUtils.getOctet1(buffer, 11 + offset);
		setHeight((Hei_VF & 0xE0) >> 5);
		setVectorFormat((Hei_VF & 0x1F));
		
		int len=12;
/*		for (FTS_GB_LMidVectorGroup group : groupList) {
			FTS_GB_LMidVectorGroup item = new FTS_GB_LMidVectorGroup();
			len+= item.parse(buffer, offset, length);
			this.addGroupBlock(item);
		}
*/
		int restLength = getLength()-12;
		while (restLength > 0) {
			FTS_GB_LMidVectorGroup item = new FTS_GB_LMidVectorGroup();
			len += item.parse(buffer, offset + len);
			restLength -= 4;
			this.addGroupBlock(item);
		}
		
		return len;
	}

	
	
	public long getFeedbackTargerIP() {
		return feedbackTargerIP;
	}

	public void setFeedbackTargerIP(long feedbackTargerIP) {
		this.feedbackTargerIP = feedbackTargerIP;
	}

	public long getFeedbackTargetPort() {
		return feedbackTargetPort;
	}

	public void setFeedbackTargetPort(long feedbackTargetPort) {
		this.feedbackTargetPort = feedbackTargetPort;
	}

	public long getGroupSize() {
		return groupSize;
	}

	public void setGroupSize(long groupSize) {
		this.groupSize = groupSize;
	}



	public int getLength() {
		return length;
	}

	public void setLength(int length) {
		this.length = length;
	}


/*
	public long getLMidVector() {
		return LMidVector;
	}

	public void setLMidVector(long midVector) {
		LMidVector = midVector;
	}
*/
	/**
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return new ToStringBuilder(this).append("feedbackTargetPort",
				this.feedbackTargetPort)
				.append("groupSize",
						this.groupSize).append("lenght", this.length).append(
						"feedbackTargerIP", this.feedbackTargerIP).toString();
	}

	public int getSFTST() {
		return SFTST;
	}

	public void setSFTST(int sftst) {
		SFTST = sftst;
	}

	public int getPadding() {
		return padding;
	}

	public void setPadding(int padding) {
		this.padding = padding;
	}

	public int getPriority() {
		return priority;
	}

	public void setPriority(int priority) {
		this.priority = priority;
	}

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public long getVectorFormat() {
		return vectorFormat;
	}

	public void setVectorFormat(long vectorFormat) {
		this.vectorFormat = vectorFormat;
	}
	
}
