package com.libreecm.commonAPI.model.objects.properties;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.libreecm.commonAPI.auxiliars.exceptions.NotDefinedIdPropertyDataException;
import com.libreecm.commonAPI.model.enums.PropertyType;
import com.libreecm.commonAPI.model.objects.ExtensionsData;

/**
 * Defines a property
 * 
 * @param <T>
 */

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class")
public abstract class PropertyData<T> extends ExtensionsData{

	private PropertyDefinition<T> propDef;
	@JsonIgnore
	public boolean isMultiValued(){
		return getValues().size()>1;
	}
	
	/**
	 * @return the propDef
	 */
	public PropertyDefinition<T> getPropDef() {
		return propDef;
	}

	public void setPropertyDefinition(PropertyDefinition<T> propDef) {
		this.propDef = propDef;
		if (propDef != null) {
			this.setId(propDef.getId());
			this.displayName = propDef.getDisplayName();
			this.localName = propDef.getLocalName();
			this.queryName = propDef.getQueryName();
			this.values=propDef.getDefaultValue();
			this.setExtensions(propDef.getExtensions());
		} 
	}

	/**
	 * @return the type
	 */
	public PropertyType getType() {
		return type;
	}

	/**
	 * @param type the type to set
	 */
	public void setType(PropertyType type) {
		this.type = type;
	}

	private PropertyType type;

	private List<T> values = Collections.emptyList();

	private String id;

	private String displayName;

	private String localName;

	private String queryName;

	public PropertyDefinition<T> getPropertyDefinition() {
		return propDef;
	}


	public String getId(){ 
		return id;
	}

	public void setId(String id) {
		if ((id==null) || id.isEmpty())
			throw new NotDefinedIdPropertyDataException(this.toString());
		this.id = id;
	}

	public String getDisplayName() {
		return displayName;
	}

	public void setDisplayName(String displayName) {
		this.displayName = displayName;
	}

	public String getLocalName() {
		return localName;
	}

	public void setLocalName(String localName) {
		this.localName = localName;
	}

	public String getQueryName() {
		return queryName;
	}

	public void setQueryName(String queryName) {
		this.queryName = queryName;
	}

	public List<T> getValues() {
		return values;
	}

	public void setValues(List<T> values) {
		if (values == null) {
			this.values = Collections.emptyList();
		} else {
			this.values = values;
		}
	}

	@JsonIgnore
	public void setValue(T value) {
		if (value == null) {
			values = Collections.emptyList();
		} else {
			values = new ArrayList<T>(1);
			values.add(value);
		}
	}
	@JsonIgnore
	public T getFirstValue() {
		if (values != null && !values.isEmpty()) {
			return values.get(0);
		}

		return null;
	}

	@Override
	public String toString() {
		return "Property [id=" + id + ", display Name=" + displayName + ", local name=" + localName + ", query name="
				+ queryName + ", values=" + values + "]" + super.toString();
	}

}
