package models;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

import core.services.OptionService;
import models.Question.TransitionType;
import play.Logger;
import utils.StringUtil;

@Entity
public class Slide extends ModelUuid {

	public static enum SlideType {
		BLANK, INFO, STIMULUS, DISTRACTION, QUESTION, ANSWER;

		public static SlideType tryBuildSlideTypeFromValue(String val) {
			if (StringUtil.isNil(val)) {
				return null;
			}

			for (SlideType slideType : values()) {
				if (slideType.name().equals(val)) {
					return slideType;
				}
			}

			return null;
		}
	}

	@Basic
	@Enumerated(EnumType.STRING)
	@Column(name = "typefield")
	private SlideType type;

	@Basic
	private String transitionType;

	@OneToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.REMOVE })
	private List<Option> options = new LinkedList<Option>();

	@OneToMany(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.REMOVE })
	private List<SlideContentComponent> slideContent = new LinkedList<SlideContentComponent>();

	@Basic
	@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.DETACH })
	private Question question;

	@Basic
	private Boolean deleted = false;
	
	@Basic
	private Date creationDate = new Date();
	
	@Basic
	private Integer orderNum;

	public Date getCreationDate() {
		return creationDate;
	}

	public void setCreationDate(Date creationDate) {
		this.creationDate = creationDate;
	}

	public Integer getOrder() {
		return orderNum;
	}

	public void setOrder(Integer order) {
		this.orderNum = order;
	}

	public SlideType getType() {
		return type;
	}

	public void setType(SlideType type) {
		this.type = type;
	}

	public String getTransitionType() {
		return transitionType;
	}

	public void setTransitionType(String transitionType) {
		this.transitionType = transitionType;
	}

	public List<Option> getOptions() {
		return options;
	}

	public void setOptions(List<Option> options) {
		this.options = options;
	}

	public List<SlideContentComponent> getSlideContent() {
		return slideContent;
	}

	public void setSlideContent(List<SlideContentComponent> slideContent) {
		this.slideContent = slideContent;
	}

	public Question getQuestion() {
		return question;
	}

	public void setQuestion(Question question) {
		this.question = question;
	}

	public Boolean getDeleted() {
		return deleted;
	}

	public void setDeleted(Boolean deleted) {
		this.deleted = deleted;
	}

	public boolean addOption(Option option) {
		if (option == null)
			return false;
		if (this.options.contains(option)) {
			return false;
		}
		return this.options.add(option);
	}

	public boolean addSlideContentComponent(SlideContentComponent slideContent) {
		if (slideContent == null)
			return false;
		if (this.slideContent.contains(slideContent)) {
			return false;
		}
		return this.slideContent.add(slideContent);
	}

	public Slide clone(Question question) throws Exception {
		if (question == null)
			throw new RuntimeException("Question is null!");

		try {
			OptionService optionService = OptionService.instance();
			Slide clonedSlide = new Slide();
			clonedSlide.setQuestion(question);
			clonedSlide.setType(this.getType());
			clonedSlide.setTransitionType(this.getTransitionType());
			clonedSlide.setDeleted(this.getDeleted());
			clonedSlide.save();
			question.addSlide(clonedSlide);
			question.save();

			List<Option> clonedOptions = optionService.cloneOptionsList(null, null, clonedSlide, null,
					this.getOptions());
			clonedSlide.setOptions(clonedOptions);
			clonedSlide.save();

			List<SlideContentComponent> clonedSlideContentComponents = new LinkedList<SlideContentComponent>();
			for (SlideContentComponent originalSlideContentComponent : this.getSlideContent()) {
				SlideContentComponent clonedSlideContentComponent = new SlideContentComponent();
				clonedSlideContentComponent.setComponentType(originalSlideContentComponent.getComponentType());
				clonedSlideContentComponent.setDim(originalSlideContentComponent.getDim());
				clonedSlideContentComponent.setMedia(originalSlideContentComponent.getMedia());
				clonedOptions = optionService.cloneOptionsList(null, null, null, originalSlideContentComponent,
						originalSlideContentComponent.getOptions());
				clonedSlideContentComponent.setOptions(clonedOptions);
				clonedSlideContentComponent.setPos(originalSlideContentComponent.getPos());
				clonedSlideContentComponent.setSlide(clonedSlide);
				clonedSlideContentComponent.setTest(question.getTest());
				clonedSlideContentComponent.save();
				clonedSlideContentComponents.add(clonedSlideContentComponent);
			}
			clonedSlide.setSlideContent(clonedSlideContentComponents);
			clonedSlide.save();

			return clonedSlide;
		} catch (Exception ex) {
			Logger.error(ex, "Exception during Slide clonation...return null");
			return null;
		}
	}

	public List<TransitionType> retrieveTransitionTypes() {
		String transitionTypes = getTransitionType();
		List<TransitionType> ret = TransitionType.buildTransitionTypesListFromString(transitionTypes);
		return ret;
	}

	public void setupTransitionTypes(List<TransitionType> transitionTypesList) {
		String transitionTypes = TransitionType.buildTransitionTypesStringFromList(transitionTypesList);
		setTransitionType(transitionTypes);
	}
}