package org.gcube.portlets.user.reportgenerator.client.targets;

import java.util.ArrayList;

import org.gcube.portlets.d4sreporting.common.shared.BasicComponent;
import org.gcube.portlets.d4sreporting.common.shared.ComponentType;
import org.gcube.portlets.d4sreporting.common.shared.RepeatableSequence;
import org.gcube.portlets.user.reportgenerator.client.Presenter.Presenter;
import org.gcube.portlets.user.reportgenerator.client.model.TemplateComponent;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.VerticalPanel;

public class ClientRepeatableSequence extends Composite implements ClientSequence {
	protected ArrayList<TemplateComponent> groupedComponents = new ArrayList<TemplateComponent>();

	private VerticalPanel myPanel = new VerticalPanel();
	private Presenter p;

	protected RepeatableSequence repSequence;

	protected RepeatableSequence originalSequence = new RepeatableSequence();

	/**
	 * constructor used by the system when reading the model 
	 * @param sRS the sequence to repeat
	 */
	public ClientRepeatableSequence(Presenter p, RepeatableSequence sRS) {
		this.p = p;
		this.repSequence = sRS;
		this.originalSequence = extractOriginalSequence(sRS);
		SequenceWidget seqW = new SequenceWidget(p, this, originalSequence, true, false);
		myPanel.add(seqW);
				
		for (RepeatableSequence repeatSeq : getRepeats()) {			
			addAnother(repeatSeq);
		}
		initWidget(myPanel);
	}

	/**
	 * when you repeat a sequence the model is not able to recognize is this was a sequence or not
	 * to overcome this limitation you have to identify the original sequence by identifying it
	 * to identify it you can use the  REPEAT_SEQUENCE_DELIMITER ELEMENT
	 * @param sRS
	 */
	private RepeatableSequence extractOriginalSequence(RepeatableSequence sRS) {
		RepeatableSequence toReturn = null;
		int repeatDelimiterCounter = 2;
		ArrayList<BasicComponent> groupedComponents = new ArrayList<BasicComponent>();

		for (BasicComponent comp : sRS.getGroupedComponents()) {			
			if (comp.getType() == ComponentType.REPEAT_SEQUENCE_DELIMITER) {
				repeatDelimiterCounter--;
			}
			if (comp.getType() != ComponentType.REPEAT_SEQUENCE_INNER) 
				groupedComponents.add(comp);

			if (repeatDelimiterCounter == 0) {
				toReturn = new RepeatableSequence(groupedComponents, sRS.getHeight());			
				return toReturn;
			}				
		}
		return toReturn;
	}
	/**
	 * 
	 * @return
	 */
	private ArrayList<RepeatableSequence> getRepeats() {
		ArrayList<RepeatableSequence> toReturn = new ArrayList<RepeatableSequence>();
		int repeatDelimiterCounter = 2;

		ArrayList<BasicComponent> groupedComponents = new ArrayList<BasicComponent>();
		for (BasicComponent comp : repSequence.getGroupedComponents()) {			
			if (comp.getType() == ComponentType.REPEAT_SEQUENCE_DELIMITER) {
				repeatDelimiterCounter--;
			}
			if (comp.getType() != ComponentType.REPEAT_SEQUENCE_INNER) 
				groupedComponents.add(comp);

			if (repeatDelimiterCounter == 0) {
				toReturn.add(new RepeatableSequence(groupedComponents, repSequence.getHeight()));
				repeatDelimiterCounter = 2;
			    groupedComponents = new ArrayList<BasicComponent>();
			}				
		}
		//if there is only the first  sequence return nothing
		if (toReturn.size() <= 1) {
			toReturn = new ArrayList<RepeatableSequence>();
		}
		else //return all of them without the first one
			toReturn.remove(0);
		return toReturn;
	}

	public void add(TemplateComponent toAdd) {
		if (toAdd.getType() != ComponentType.REPEAT_SEQUENCE_INNER) {
			groupedComponents.add(toAdd);
			GWT.log("ToAdd= getType " + toAdd.getType());
			myPanel.add(toAdd.getContent());
		}
	}

	protected void addAnother(RepeatableSequence sRS) {
		SequenceWidget seqW = new SequenceWidget(p, this, sRS, false, false);
		myPanel.add(seqW);
	}
	

	protected void addNew(RepeatableSequence sRS) {
		SequenceWidget seqW = new SequenceWidget(p, this, sRS, false, true);
		myPanel.add(seqW);
	}
	/**
	 * remove the widget and its components
	 * @param toRemove
	 */
	protected void removeSeqWidget(SequenceWidget toRemove) {
		myPanel.remove(toRemove);
		for (TemplateComponent tc : toRemove.getSeqGroupedComponents()) {
			groupedComponents.remove(tc);
		}
	}
	
	@Override
	public ArrayList<TemplateComponent> getGroupedComponents() {
		return groupedComponents;
	}

	public void setGroupedComponents(ArrayList<TemplateComponent> groupedComponents) {
		this.groupedComponents = groupedComponents;
	}

	@Override
	public boolean add(RepeatableSequence sequence) {
		SequenceWidget seqW = new SequenceWidget(p, this, sequence, false, true);
		myPanel.add(seqW);
		return true;
	}

	@Override
	public SequenceWidget remove(SequenceWidget toRemove) {
		myPanel.remove(toRemove);
		for (TemplateComponent tc : toRemove.getSeqGroupedComponents()) {
			groupedComponents.remove(tc);
		}
		return toRemove;
	}	
}
