package com.libreecm.commonAPI.model.objects;


import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.libreecm.commonAPI.model.enums.BaseTypeId;
import com.libreecm.commonAPI.model.enums.Cardinality;
import com.libreecm.commonAPI.model.enums.MimeType;
import com.libreecm.commonAPI.model.enums.PropertyIds;
import com.libreecm.commonAPI.model.enums.PropertyType;
import com.libreecm.commonAPI.model.enums.Updatability;
import com.libreecm.commonAPI.model.objects.properties.PropertyBooleanDefinitionImpl;
import com.libreecm.commonAPI.model.objects.properties.PropertyDateTimeDefinitionImpl;
import com.libreecm.commonAPI.model.objects.properties.PropertyIdDefinitionImpl;
import com.libreecm.commonAPI.model.objects.properties.PropertyIntegerDefinitionImpl;
import com.libreecm.commonAPI.model.objects.properties.PropertyStringDefinitionImpl;


@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class Document extends LibreECMDataObject {

	/**
	 * 
	 */
	private static final long serialVersionUID = 3834570477805554793L;

	private String checkinComment;
	private String contentStreamFileName;
	private String contentStreamHash;
	private String contentStreamId;
	private BigInteger contentStreamLength;
	private String contentStreamMimeType;


	private boolean immutable;


	private Boolean includedInSupertypeQuery;


	private boolean latestMajorVersion;


	private boolean latestVersion;


	private boolean majorVersion;


	private Boolean versionable;


	private boolean versionSeriesCheckedOut;

	private String versionLabel;
	private String versionSeriesCheckedOutBy;
	private String versionSeriesCheckedOutId;

	private String versionSeriesId;

	
	public Document(){
		super();
		//For jackson, setObjectType SHOULD be called first
		super.setObjectType(new DocumentObjectType());
		super.setBaseTypeId(BaseTypeId.CMIS_DOCUMENT);
	}

	public Document(Uri uri, ObjectType objectType){
		super(uri, objectType);
	}
	
	/**
	 * @return the checkinComment
	 */
	public String getCheckinComment() {
		return checkinComment;
	}

	/**
	 * @return the contentStreamFileName
	 */
	public String getContentStreamFileName() {
		return contentStreamFileName;
	}

	/**
	 * @return the contentStreamHash
	 */
	public String getContentStreamHash() {
		return contentStreamHash;
	}

	/**
	 * @return the contentStreamId
	 */
	public String getContentStreamId() {
		return contentStreamId;
	}
	
	/**
	 * @return the contentStreamLength
	 */
	public BigInteger getContentStreamLength() {
		return contentStreamLength;
	}

	/**
	 * @return the contentStreamMimeType
	 */
	public String getContentStreamMimeType() {
		return contentStreamMimeType;
	}


	/**
	 * @return the versionLabel
	 */
	public String getVersionLabel() {
		return versionLabel;
	}

	/**
	 * @return the versionSeriesCheckedOutBy
	 */
	public String getVersionSeriesCheckedOutBy() {
		return versionSeriesCheckedOutBy;
	}

	/**
	 * @return the versionSeriesCheckedOutId
	 */
	public String getVersionSeriesCheckedOutId() {
		return versionSeriesCheckedOutId;
	}

	/**
	 * @return the versionSeriesId
	 */
	public String getVersionSeriesId() {
		return versionSeriesId;
	}


	/**
	 * @return the isImmutable
	 */
	public boolean isImmutable() {
		return immutable;
	}

	public Boolean isIncludedInSupertypeQuery() {
		return includedInSupertypeQuery;
	}

	/**
	 * @return the isLatestMajorVersion
	 */
	public boolean isLatestMajorVersion() {
		return latestMajorVersion;
	}

	/**
	 * @return the isLatestVersion
	 */
	public boolean isLatestVersion() {
		return latestVersion;
	}

	/**
	 * @return the isMajorVersion
	 */
	public boolean isMajorVersion() {
		return majorVersion;
	}

	public Boolean isVersionable() {
		return this.versionable;
	}
	
	/**
	 * @return the isVersionSeriesCheckedOut
	 */
	public boolean isVersionSeriesCheckedOut() {

		return versionSeriesCheckedOut;
	}

	/**
	 * @param checkinComment the checkinComment to set
	 */
	public void setCheckinComment(String checkinComment) {
		if (checkinComment == null) return;
		addStringProperty(PropertyIds.CHECKIN_COMMENT, checkinComment);
		this.checkinComment = checkinComment;
	}

	/**
	 * @param contentStreamFileName the contentStreamFileName to set
	 */
	public void setContentStreamFileName(String contentStreamFileName) {
		if (contentStreamFileName == null) return;
		addStringProperty(PropertyIds.CONTENT_STREAM_FILE_NAME, contentStreamFileName);
		this.contentStreamFileName = contentStreamFileName;
	}

	/**
	 * @param contentStreamHash the contentStreamHash to set
	 */
	public void setContentStreamHash(String contentStreamHash) {
		if (contentStreamHash == null) return;
		addStringProperty(PropertyIds.CONTENT_STREAM_HASH, contentStreamHash);
		this.contentStreamHash = contentStreamHash;
	}

	/**
	 * @param contentStreamId the contentStreamId to set
	 */
	public void setContentStreamId(String contentStreamId) {
		if (contentStreamId == null) return;
		addStringProperty(PropertyIds.CONTENT_STREAM_ID, contentStreamId);
		this.contentStreamId = contentStreamId;
	}

	/**
	 * @param contentStreamLength the contentStreamLength to set
	 */
	public void setContentStreamLength(BigInteger contentStreamLength) {
		if (contentStreamLength == null) return;
		addIntegerProperty(PropertyIds.CONTENT_STREAM_LENGTH, contentStreamLength);
		this.contentStreamLength = contentStreamLength;
	}

	/**
	 * @param contentStreamMimeType the contentStreamMimeType to set
	 */
	public void setContentStreamMimeType(String contentStreamMimeType) {
		if (contentStreamMimeType == null) return;
		addStringProperty(PropertyIds.CONTENT_STREAM_MIME_TYPE, contentStreamMimeType);
		this.contentStreamMimeType = contentStreamMimeType;
	}

	/**
	 * @param isImmutable the isImmutable to set
	 */
	public void setImmutable(Boolean isImmutable) {
		if (isImmutable== null) return;
		addBooleanProperty(PropertyIds.IS_IMMUTABLE, isImmutable);
		this.immutable = isImmutable;
	}

	/**
	 * @param isIncludedInSupertypeQuery the isIncludedInSupertypeQuery to set
	 */
	public void setIncludedInSupertypeQuery(Boolean isIncludedInSupertypeQuery) {
		if (isIncludedInSupertypeQuery == null) return;
		addBooleanProperty("cmis:includedInSupertypeQuery", isIncludedInSupertypeQuery);
		this.includedInSupertypeQuery = isIncludedInSupertypeQuery;
	}

	/**
	 * @param isVersionable the isVersionable to set
	 */
	public void setVersionable(Boolean isVersionable) {
		if (isVersionable == null) return;
		addBooleanProperty("cmis:versionable", isVersionable);
		this.versionable = isVersionable;
	}

	/**
	 * @param isLatestMajorVersion the isLatestMajorVersion to set
	 */
	public void setLatestMajorVersion(Boolean isLatestMajorVersion) {
		if (isLatestMajorVersion == null) return;
		addBooleanProperty(PropertyIds.IS_LATEST_MAJOR_VERSION, isLatestMajorVersion);
		this.latestMajorVersion = isLatestMajorVersion;
	}

	/**
	 * @param isLatestVersion the isLatestVersion to set
	 */
	public void setLatestVersion(Boolean isLatestVersion) {
		if (isLatestVersion == null) return;
		addBooleanProperty(PropertyIds.IS_LATEST_VERSION, isLatestVersion);
		this.latestVersion = isLatestVersion;
	}

	/**
	 * @param isMajorVersion the isMajorVersion to set
	 */
	public void setMajorVersion(Boolean isMajorVersion) {
		if (isMajorVersion == null) return;
		addBooleanProperty(PropertyIds.IS_MAJOR_VERSION, isMajorVersion);
		this.majorVersion = isMajorVersion;
	}
	/**
	 * @param versionLabel the versionLabel to set
	 */
	public void setVersionLabel(String versionLabel) {
		if (versionLabel == null) return;
		addStringProperty(PropertyIds.VERSION_LABEL, versionLabel);
		this.versionLabel = versionLabel;
	}
	/**
	 * @param isVersionSeriesCheckedOut the isVersionSeriesCheckedOut to set
	 */
	public void setVersionSeriesCheckedOut(Boolean isVersionSeriesCheckedOut) {
		if (isVersionSeriesCheckedOut == null) return;
		addBooleanProperty(PropertyIds.IS_VERSION_SERIES_CHECKED_OUT, isVersionSeriesCheckedOut);
		this.versionSeriesCheckedOut = isVersionSeriesCheckedOut;
	}
	
	/**
	 * @param versionSeriesCheckedOutBy the versionSeriesCheckedOutBy to set
	 */
	public void setVersionSeriesCheckedOutBy(String versionSeriesCheckedOutBy) {
		if (versionSeriesCheckedOutBy == null) return;
		addStringProperty(PropertyIds.VERSION_SERIES_CHECKED_OUT_BY, versionSeriesCheckedOutBy);
		this.versionSeriesCheckedOutBy = versionSeriesCheckedOutBy;
	} 

	
	/**
	 * @param versionSeriesCheckedOutId the versionSeriesCheckedOutId to set
	 */
	public void setVersionSeriesCheckedOutId(String versionSeriesCheckedOutId) {
		if (versionSeriesCheckedOutId == null) return;
		addStringProperty(PropertyIds.VERSION_SERIES_CHECKED_OUT_ID, versionSeriesCheckedOutId);
		this.versionSeriesCheckedOutId = versionSeriesCheckedOutId;
	}
	
	/**
	 * @param versionSeriesId the versionSeriesId to set
	 */
	public void setVersionSeriesId(String versionSeriesId) {
		if (versionSeriesId == null) return;
		addStringProperty(PropertyIds.VERSION_SERIES_ID, versionSeriesId);
		this.versionSeriesId = versionSeriesId;
	}

}