<?php
/**
 * IndiciaImbRequestDescription
 *
 * PHP version 5
 *
 * @category Class
 * @package  USPS\Labels
 * @author   Swagger Codegen team
 * @link     https://github.com/swagger-api/swagger-codegen
 */

/**
 * Labels
 *
 * Contact Us: [USPS API Support](https://emailus.usps.com/s/usps-APIs) | [Terms of Service](https://about.usps.com/termsofuse.htm)  The USPS&#174; Labels API allows you to digitally create mailing labels for the following mail classes: USPS Ground Advantage&#8482;, Parcel Select&#174; Destination Entry, Parcel Select Lightweight&#174;, USPS Connect&#174; Local, USPS Connect&#174; Regional, Priority  Mail&#174;, Priority Mail Express&#174;, Bound Printed Matter, Library Mail, and Media Mail&#174;.  * Use the [Getting Started guide](https://developers.usps.com/getting-started) to get started with the Labels API. * The USPS&#174; Labels API uses a token to authorize the use of an [Enterprise Payment](https://postalpro.usps.com/EPS) or Permit account. The specification to generate the token is in the [Payments 3.0 - Set Payment Account Information](https://developers.usps.com/paymentsv3#tag/Resources/operation/post-payments-payment-authorization).  **Manifest Scheduling**   The following table outlines the Domestic Label manifesting schedule for specific conditions listed below.   | Condition                   | Scheduling | | ----------------------------| -------- | | **Customs Forms labels**    | 12:30am CT on the day after label creation. | | **Return labels**    | 12:30am CT on the day after label creation. | | **Smart Locker labels**     | Electronic data is sent to Postal systems within 15 minutes of label creation. | | **Value of `true` provided for `immediateManifest` field**| Electronic data is sent to Postal systems within 15 minutes of label creation.  | | **Label is added to a [SCAN Form](https://developers.usps.com/scanv3#tag/Resources/operation/post-scan-form)**| Electronic data is sent to Postal systems within 15 minutes of SCAN Form creation.  | | **All other conditions**    | 12:30am CT after the `mailingDate` value provided by the user |
 *
 * OpenAPI spec version: 3.9.9
 * 
 * Generated by: https://github.com/swagger-api/swagger-codegen.git
 * Swagger Codegen version: 3.0.71
 */
/**
 * NOTE: This class is auto generated by the swagger code generator program.
 * https://github.com/swagger-api/swagger-codegen
 * Do not edit the class manually.
 */

namespace USPS\Labels\Model;

use \ArrayAccess;
use \USPS\Labels\ObjectSerializer;

/**
 * IndiciaImbRequestDescription Class Doc Comment
 *
 * @category Class
 * @description Indicia intelligent mail barcode request description
 * @package  USPS\Labels
 * @author   Swagger Codegen team
 * @link     https://github.com/swagger-api/swagger-codegen
 */
class IndiciaImbRequestDescription implements ModelInterface, ArrayAccess
{
    const DISCRIMINATOR = null;

    /**
      * The original name of the model.
      *
      * @var string
      */
    protected static $swaggerModelName = 'IndiciaImbRequestDescription';

    /**
      * Array of property to type mappings. Used for (de)serialization
      *
      * @var string[]
      */
    protected static $swaggerTypes = [
        'processing_category' => 'string',
        'weight' => 'float',
        'mailing_date' => '\USPS\Labels\Model\MailingDateIndiciaOptions',
        'length' => 'double',
        'height' => 'double',
        'thickness' => 'double',
        'item_value' => 'float',
        'extra_services' => '\USPS\Labels\Model\IndiciaImbExtraService[]',
        'non_machinable_indicators' => '\USPS\Labels\Model\IndiciaImbRequestDescriptionNonMachinableIndicators',
        'imi_type' => '\USPS\Labels\Model\IMIType'
    ];

    /**
      * Array of property to format mappings. Used for (de)serialization
      *
      * @var string[]
      */
    protected static $swaggerFormats = [
        'processing_category' => null,
        'weight' => null,
        'mailing_date' => null,
        'length' => 'double',
        'height' => 'double',
        'thickness' => 'double',
        'item_value' => null,
        'extra_services' => null,
        'non_machinable_indicators' => null,
        'imi_type' => null
    ];

    /**
     * Array of property to type mappings. Used for (de)serialization
     *
     * @return array
     */
    public static function swaggerTypes()
    {
        return self::$swaggerTypes;
    }

    /**
     * Array of property to format mappings. Used for (de)serialization
     *
     * @return array
     */
    public static function swaggerFormats()
    {
        return self::$swaggerFormats;
    }

    /**
     * Array of attributes where the key is the local name,
     * and the value is the original name
     *
     * @var string[]
     */
    protected static $attributeMap = [
        'processing_category' => 'processingCategory',
        'weight' => 'weight',
        'mailing_date' => 'mailingDate',
        'length' => 'length',
        'height' => 'height',
        'thickness' => 'thickness',
        'item_value' => 'itemValue',
        'extra_services' => 'extraServices',
        'non_machinable_indicators' => 'nonMachinableIndicators',
        'imi_type' => 'imiType'
    ];

    /**
     * Array of attributes to setter functions (for deserialization of responses)
     *
     * @var string[]
     */
    protected static $setters = [
        'processing_category' => 'setProcessingCategory',
        'weight' => 'setWeight',
        'mailing_date' => 'setMailingDate',
        'length' => 'setLength',
        'height' => 'setHeight',
        'thickness' => 'setThickness',
        'item_value' => 'setItemValue',
        'extra_services' => 'setExtraServices',
        'non_machinable_indicators' => 'setNonMachinableIndicators',
        'imi_type' => 'setImiType'
    ];

    /**
     * Array of attributes to getter functions (for serialization of requests)
     *
     * @var string[]
     */
    protected static $getters = [
        'processing_category' => 'getProcessingCategory',
        'weight' => 'getWeight',
        'mailing_date' => 'getMailingDate',
        'length' => 'getLength',
        'height' => 'getHeight',
        'thickness' => 'getThickness',
        'item_value' => 'getItemValue',
        'extra_services' => 'getExtraServices',
        'non_machinable_indicators' => 'getNonMachinableIndicators',
        'imi_type' => 'getImiType'
    ];

    /**
     * Array of attributes where the key is the local name,
     * and the value is the original name
     *
     * @return array
     */
    public static function attributeMap()
    {
        return self::$attributeMap;
    }

    /**
     * Array of attributes to setter functions (for deserialization of responses)
     *
     * @return array
     */
    public static function setters()
    {
        return self::$setters;
    }

    /**
     * Array of attributes to getter functions (for serialization of requests)
     *
     * @return array
     */
    public static function getters()
    {
        return self::$getters;
    }

    /**
     * The original name of the model.
     *
     * @return string
     */
    public function getModelName()
    {
        return self::$swaggerModelName;
    }

    const PROCESSING_CATEGORY_LETTERS = 'LETTERS';
    const PROCESSING_CATEGORY_FLATS = 'FLATS';
    const PROCESSING_CATEGORY_CARDS = 'CARDS';

    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getProcessingCategoryAllowableValues()
    {
        return [
            self::PROCESSING_CATEGORY_LETTERS,
            self::PROCESSING_CATEGORY_FLATS,
            self::PROCESSING_CATEGORY_CARDS,
        ];
    }

    /**
     * Associative array for storing property values
     *
     * @var mixed[]
     */
    protected $container = [];

    /**
     * Constructor
     *
     * @param mixed[] $data Associated array of property values
     *                      initializing the model
     */
    public function __construct(array $data = null)
    {
        $this->container['processing_category'] = isset($data['processing_category']) ? $data['processing_category'] : null;
        $this->container['weight'] = isset($data['weight']) ? $data['weight'] : null;
        $this->container['mailing_date'] = isset($data['mailing_date']) ? $data['mailing_date'] : null;
        $this->container['length'] = isset($data['length']) ? $data['length'] : null;
        $this->container['height'] = isset($data['height']) ? $data['height'] : null;
        $this->container['thickness'] = isset($data['thickness']) ? $data['thickness'] : null;
        $this->container['item_value'] = isset($data['item_value']) ? $data['item_value'] : null;
        $this->container['extra_services'] = isset($data['extra_services']) ? $data['extra_services'] : null;
        $this->container['non_machinable_indicators'] = isset($data['non_machinable_indicators']) ? $data['non_machinable_indicators'] : null;
        $this->container['imi_type'] = isset($data['imi_type']) ? $data['imi_type'] : null;
    }

    /**
     * Show all the invalid properties with reasons.
     *
     * @return array invalid properties with reasons
     */
    public function listInvalidProperties()
    {
        $invalidProperties = [];

        if ($this->container['processing_category'] === null) {
            $invalidProperties[] = "'processing_category' can't be null";
        }
        $allowedValues = $this->getProcessingCategoryAllowableValues();
        if (!is_null($this->container['processing_category']) && !in_array($this->container['processing_category'], $allowedValues, true)) {
            $invalidProperties[] = sprintf(
                "invalid value for 'processing_category', must be one of '%s'",
                implode("', '", $allowedValues)
            );
        }

        if ($this->container['weight'] === null) {
            $invalidProperties[] = "'weight' can't be null";
        }
        if ($this->container['mailing_date'] === null) {
            $invalidProperties[] = "'mailing_date' can't be null";
        }
        if ($this->container['length'] === null) {
            $invalidProperties[] = "'length' can't be null";
        }
        if ($this->container['height'] === null) {
            $invalidProperties[] = "'height' can't be null";
        }
        if ($this->container['thickness'] === null) {
            $invalidProperties[] = "'thickness' can't be null";
        }
        return $invalidProperties;
    }

    /**
     * Validate all the properties in the model
     * return true if all passed
     *
     * @return bool True if all properties are valid
     */
    public function valid()
    {
        return count($this->listInvalidProperties()) === 0;
    }


    /**
     * Gets processing_category
     *
     * @return string
     */
    public function getProcessingCategory()
    {
        return $this->container['processing_category'];
    }

    /**
     * Sets processing_category
     *
     * @param string $processing_category * LETTERS                  To be eligible for mailing at the price for letters, a piece must be:     * Rectangular     * At least 3-1/2 inches high x 5 inches long x 0.007 inch thick.     * No more than 6-1/8 inches high x 11-1/2 inches long x 1/4 inch thick.    For additional information on letters, please refer to the [Postal Explorer](https://pe.usps.com/businessmail101?ViewName=Letters).  * FLATS     The Postal Service uses the word \"flats\" to refer to large envelopes, newsletters, and magazines. The words large envelopes and flats are used interchangeably. Whatever you call them, flats must:      * Have one dimension that is greater than 6-1/8 inches high OR 11-½ inches long OR ¼ inch thick.     * Be no more than 12 inches high x 15 inches long x ¾ inch thick.    For additional information on flats, please refer to the [Postal Explorer](https://pe.usps.com/businessmail101?ViewName=Flats).  * CARDS     To be eligible for mailing at the price for postcards, a piece must be:     * Rectangular     * At least 3-1/2 inches high x 5 inches long x 0.007 inch thick.     * No more than 4-1/4 inches high x 6 inches long x 0.016 inch thick.    For additional information on postcards, please refer to the [Postal Explorer](https://pe.usps.com/businessmail101?ViewName=Cards).
     *
     * @return $this
     */
    public function setProcessingCategory($processing_category)
    {
        $allowedValues = $this->getProcessingCategoryAllowableValues();
        if (!in_array($processing_category, $allowedValues, true)) {
            throw new \InvalidArgumentException(
                sprintf(
                    "Invalid value for 'processing_category', must be one of '%s'",
                    implode("', '", $allowedValues)
                )
            );
        }
        $this->container['processing_category'] = $processing_category;

        return $this;
    }

    /**
     * Gets weight
     *
     * @return float
     */
    public function getWeight()
    {
        return $this->container['weight'];
    }

    /**
     * Sets weight
     *
     * @param float $weight The letter/flat/card weight, in ounces. The maximum weight of a letter and cards is 3.5 oz and the maximum weight of a flat is 13 oz.
     *
     * @return $this
     */
    public function setWeight($weight)
    {
        $this->container['weight'] = $weight;

        return $this;
    }

    /**
     * Gets mailing_date
     *
     * @return \USPS\Labels\Model\MailingDateIndiciaOptions
     */
    public function getMailingDate()
    {
        return $this->container['mailing_date'];
    }

    /**
     * Sets mailing_date
     *
     * @param \USPS\Labels\Model\MailingDateIndiciaOptions $mailing_date mailing_date
     *
     * @return $this
     */
    public function setMailingDate($mailing_date)
    {
        $this->container['mailing_date'] = $mailing_date;

        return $this;
    }

    /**
     * Gets length
     *
     * @return double
     */
    public function getLength()
    {
        return $this->container['length'];
    }

    /**
     * Sets length
     *
     * @param double $length The letter/flat/card length in inches.  For  `LETTERS` and `CARDS` the length is the dimension parallel to the delivery address as read. For  `FLATS` the length is the longest dimension.
     *
     * @return $this
     */
    public function setLength($length)
    {
        $this->container['length'] = $length;

        return $this;
    }

    /**
     * Gets height
     *
     * @return double
     */
    public function getHeight()
    {
        return $this->container['height'];
    }

    /**
     * Sets height
     *
     * @param double $height The letter/flat/card height in inches.  The height is the dimension perpendicular to the length.
     *
     * @return $this
     */
    public function setHeight($height)
    {
        $this->container['height'] = $height;

        return $this;
    }

    /**
     * Gets thickness
     *
     * @return double
     */
    public function getThickness()
    {
        return $this->container['thickness'];
    }

    /**
     * Sets thickness
     *
     * @param double $thickness The letter/flat/card thickness in inches. The minimum dimension is always the thickness.
     *
     * @return $this
     */
    public function setThickness($thickness)
    {
        $this->container['thickness'] = $thickness;

        return $this;
    }

    /**
     * Gets item_value
     *
     * @return float
     */
    public function getItemValue()
    {
        return $this->container['item_value'];
    }

    /**
     * Sets item_value
     *
     * @param float $item_value Value of the letter, flat, or card in USD.  Note:   * This value must be set if extra service codes 930 (Insurance) or 934 (Insurance (Restricted Delivery)) are in the extraServices field.
     *
     * @return $this
     */
    public function setItemValue($item_value)
    {
        $this->container['item_value'] = $item_value;

        return $this;
    }

    /**
     * Gets extra_services
     *
     * @return \USPS\Labels\Model\IndiciaImbExtraService[]
     */
    public function getExtraServices()
    {
        return $this->container['extra_services'];
    }

    /**
     * Sets extra_services
     *
     * @param \USPS\Labels\Model\IndiciaImbExtraService[] $extra_services Extra Service Code requested for IMB letters, flats, and cards.    * 910 - Certified Mail   * 911 - Certified Mail Restricted Delivery   * 930 - Insurance   * 934 - Insurance Restricted Delivery   * 940 - Registered Mail   * 941 - Registered Mail Restricted Delivery   * 955 - Return Receipt   * 957 - Return Receipt Electronic  Note:   * When the extra service code \"930\" is provided in the request, if the item value is over $500, \"930\" will automatically be replaced with \"931\" - Insurance (Greater than $500).   * Some service codes require a combination with extra services such as \"955\" and \"957\". For all valid combinations, visit [https://postalpro.usps.com/IMPB_Service_Type_Codes](https://postalpro.usps.com/IMPB_Service_Type_Codes).
     *
     * @return $this
     */
    public function setExtraServices($extra_services)
    {
        $this->container['extra_services'] = $extra_services;

        return $this;
    }

    /**
     * Gets non_machinable_indicators
     *
     * @return \USPS\Labels\Model\IndiciaImbRequestDescriptionNonMachinableIndicators
     */
    public function getNonMachinableIndicators()
    {
        return $this->container['non_machinable_indicators'];
    }

    /**
     * Sets non_machinable_indicators
     *
     * @param \USPS\Labels\Model\IndiciaImbRequestDescriptionNonMachinableIndicators $non_machinable_indicators non_machinable_indicators
     *
     * @return $this
     */
    public function setNonMachinableIndicators($non_machinable_indicators)
    {
        $this->container['non_machinable_indicators'] = $non_machinable_indicators;

        return $this;
    }

    /**
     * Gets imi_type
     *
     * @return \USPS\Labels\Model\IMIType
     */
    public function getImiType()
    {
        return $this->container['imi_type'];
    }

    /**
     * Sets imi_type
     *
     * @param \USPS\Labels\Model\IMIType $imi_type imi_type
     *
     * @return $this
     */
    public function setImiType($imi_type)
    {
        $this->container['imi_type'] = $imi_type;

        return $this;
    }
    /**
     * Returns true if offset exists. False otherwise.
     *
     * @param integer $offset Offset
     *
     * @return boolean
     */
    #[\ReturnTypeWillChange]
    public function offsetExists($offset)
    {
        return isset($this->container[$offset]);
    }

    /**
     * Gets offset.
     *
     * @param integer $offset Offset
     *
     * @return mixed
     */
    #[\ReturnTypeWillChange]
    public function offsetGet($offset)
    {
        return isset($this->container[$offset]) ? $this->container[$offset] : null;
    }

    /**
     * Sets value based on offset.
     *
     * @param integer $offset Offset
     * @param mixed   $value  Value to be set
     *
     * @return void
     */
    #[\ReturnTypeWillChange]
    public function offsetSet($offset, $value)
    {
        if (is_null($offset)) {
            $this->container[] = $value;
        } else {
            $this->container[$offset] = $value;
        }
    }

    /**
     * Unsets offset.
     *
     * @param integer $offset Offset
     *
     * @return void
     */
    #[\ReturnTypeWillChange]
    public function offsetUnset($offset)
    {
        unset($this->container[$offset]);
    }

    /**
     * Gets the string presentation of the object
     *
     * @return string
     */
    public function __toString()
    {
        if (defined('JSON_PRETTY_PRINT')) { // use JSON pretty print
            return json_encode(
                ObjectSerializer::sanitizeForSerialization($this),
                JSON_PRETTY_PRINT
            );
        }

        return json_encode(ObjectSerializer::sanitizeForSerialization($this));
    }
}
