"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Recurrence = void 0;
const ArgumentException_1 = require("../../../Exceptions/ArgumentException");
const DateTime_1 = require("../../../DateTime");
const EndDateRecurrenceRange_1 = require("../Ranges/EndDateRecurrenceRange");
const NoEndRecurrenceRange_1 = require("../Ranges/NoEndRecurrenceRange");
const NumberedRecurrenceRange_1 = require("../Ranges/NumberedRecurrenceRange");
const ServiceValidationException_1 = require("../../../Exceptions/ServiceValidationException");
const ExtensionMethods_1 = require("../../../ExtensionMethods");
const Strings_1 = require("../../../Strings");
const XmlNamespace_1 = require("../../../Enumerations/XmlNamespace");
const ComplexProperty_1 = require("../../ComplexProperty");
/**
 * Represents a recurrence pattern, as used by Appointment and Task items.
 */
class Recurrence extends ComplexProperty_1.ComplexProperty {
    constructor(startDate) {
        super();
        this.startDate = null;
        this.numberOfOccurrences = null;
        this.endDate = null;
        if (arguments.length === 1) {
            this.startDate = startDate;
        }
    }
    /**
     * @internal Gets the name of the XML element.
     *
     * @value   The name of the XML element.
     */
    get XmlElementName() { return null; }
    ;
    /**
     * @internal Gets a value indicating whether this instance is regeneration pattern.
     *
     * @value   *true* if this instance is regeneration pattern; otherwise, *false*.
     */
    get IsRegenerationPattern() {
        return false;
    }
    /**
     * Gets or sets the date and time when the recurrence start.
     */
    get StartDate() {
        return this.GetFieldValueOrThrowIfNull(this.startDate, "StartDate");
    }
    set StartDate(value) {
        this.startDate = new DateTime_1.DateTime(value);
    }
    /**
     * Gets a value indicating whether the pattern has a fixed number of occurrences or an end date.
     */
    get HasEnd() {
        return this.numberOfOccurrences !== null || this.endDate !== null;
    }
    /**
     * Gets or sets the number of occurrences after which the recurrence ends. Setting NumberOfOccurrences resets EndDate.
     */
    get NumberOfOccurrences() {
        return this.numberOfOccurrences;
    }
    set NumberOfOccurrences(value) {
        if (value < 1) {
            throw new ArgumentException_1.ArgumentException(Strings_1.Strings.NumberOfOccurrencesMustBeGreaterThanZero);
        }
        this.SetFieldValue({ getValue: () => this.numberOfOccurrences, setValue: (updateValue) => { this.numberOfOccurrences = updateValue; } }, value);
        this.endDate = null;
    }
    /**
     * Gets or sets the date after which the recurrence ends. Setting EndDate resets NumberOfOccurrences.
     */
    get EndDate() {
        return this.endDate;
    }
    set EndDate(value) {
        this.SetFieldValue({ getValue: () => this.endDate, setValue: (updateValue) => { this.endDate = updateValue; } }, value);
        this.numberOfOccurrences = null;
    }
    /**
     * Gets a property value or throw if null.
     *
     * @typeparam   {T}     Value type.
     * @param   {T}         value   The value.
     * @param   {string}    name    The property name.
     * @return  {T}         Property value
     */
    GetFieldValueOrThrowIfNull(value, name) {
        if (typeof value !== 'undefined' && value !== null) {
            return value;
        }
        else {
            throw new ServiceValidationException_1.ServiceValidationException(ExtensionMethods_1.StringHelper.Format(Strings_1.Strings.PropertyValueMustBeSpecifiedForRecurrencePattern, name));
        }
    }
    /**
     * @internal Validates this instance.
     */
    InternalValidate() {
        super.InternalValidate();
        if (!this.startDate) {
            throw new ServiceValidationException_1.ServiceValidationException(Strings_1.Strings.RecurrencePatternMustHaveStartDate);
        }
    }
    /**
     * @internal Write properties to XML.
     *
     * @param   {EwsServiceXmlWriter}   writer   The writer.
     */
    InternalWritePropertiesToXml(writer) { }
    /**
     * Compares two objects by converting them to JSON and comparing their string values
     *
     * @param   {Recurrence}    otherRecurrence   object to compare to
     * @return  {boolean}       true if the objects serialize to the same string
     */
    IsSame(otherRecurrence) {
        throw new Error("Recurrence.ts - IsSame : Not implemented. - no method calls it");
        // if (otherRecurrence == null) {
        //     return false;
        // }
        // string jsonString;
        // using(MemoryStream memoryStream = new MemoryStream())
        // {
        //     ((JsonObject)this.InternalToJson(null)).SerializeToJson(memoryStream);
        //     memoryStream.Position = 0;
        //     using(StreamReader reader = new StreamReader(memoryStream))
        //     {
        //         jsonString = reader.ReadToEnd();
        //     }
        // }
        // string otherJsonString;
        // using(MemoryStream memoryStream = new MemoryStream())
        // {
        //     ((JsonObject)otherRecurrence.InternalToJson(null)).SerializeToJson(memoryStream);
        //     memoryStream.Position = 0;
        //     using(StreamReader reader = new StreamReader(memoryStream))
        //     {
        //         otherJsonString = reader.ReadToEnd();
        //     }
        // }
        // return String.Equals(jsonString, otherJsonString, StringComparison.Ordinal);
    }
    /**
     * @internal Loads service object from XML.
     *
     * @param   {any}                 jsObject                Json Object converted from XML.
     * @param   {ExchangeService}     service                 The service.
     */
    LoadFromXmlJsObject(jsObject, service) {
    }
    /**
     * Sets up this recurrence so that it never ends. Calling NeverEnds is equivalent to setting both NumberOfOccurrences and EndDate to null.
     */
    NeverEnds() {
        this.numberOfOccurrences = null;
        this.endDate = null;
        this.Changed();
    }
    /**
     * @internal Writes elements to XML.
     *
     * @param   {EwsServiceXmlWriter}   writer   The writer.
     */
    WriteElementsToXml(writer) {
        writer.WriteStartElement(XmlNamespace_1.XmlNamespace.Types, this.XmlElementName);
        this.InternalWritePropertiesToXml(writer);
        writer.WriteEndElement();
        let range;
        if (!this.HasEnd) {
            range = new NoEndRecurrenceRange_1.NoEndRecurrenceRange(this.StartDate);
        }
        else if (this.NumberOfOccurrences) {
            range = new NumberedRecurrenceRange_1.NumberedRecurrenceRange(this.StartDate, this.NumberOfOccurrences);
        }
        else {
            range = new EndDateRecurrenceRange_1.EndDateRecurrenceRange(this.StartDate, this.EndDate);
        }
        range.WriteToXml(writer, range.XmlElementName);
    }
}
exports.Recurrence = Recurrence;
(function (Recurrence) {
})(Recurrence = exports.Recurrence || (exports.Recurrence = {}));
//# sourceMappingURL=Recurrence.js.map