<?php
/**
 * PackageDescription
 *
 * 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;

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

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

    /**
      * Array of property to type mappings. Used for (de)serialization
      *
      * @var string[]
      */
    protected static $swaggerTypes = [
        'weight_uom' => 'string',
        'weight' => 'float',
        'dimensions_uom' => 'string',
        'length' => 'float',
        'height' => 'float',
        'width' => 'float',
        'girth' => 'float',
        'has_nonstandard_characteristics' => 'bool'
    ];

    /**
      * Array of property to format mappings. Used for (de)serialization
      *
      * @var string[]
      */
    protected static $swaggerFormats = [
        'weight_uom' => null,
        'weight' => null,
        'dimensions_uom' => null,
        'length' => null,
        'height' => null,
        'width' => null,
        'girth' => null,
        'has_nonstandard_characteristics' => 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 = [
        'weight_uom' => 'weightUOM',
        'weight' => 'weight',
        'dimensions_uom' => 'dimensionsUOM',
        'length' => 'length',
        'height' => 'height',
        'width' => 'width',
        'girth' => 'girth',
        'has_nonstandard_characteristics' => 'hasNonstandardCharacteristics'
    ];

    /**
     * Array of attributes to setter functions (for deserialization of responses)
     *
     * @var string[]
     */
    protected static $setters = [
        'weight_uom' => 'setWeightUom',
        'weight' => 'setWeight',
        'dimensions_uom' => 'setDimensionsUom',
        'length' => 'setLength',
        'height' => 'setHeight',
        'width' => 'setWidth',
        'girth' => 'setGirth',
        'has_nonstandard_characteristics' => 'setHasNonstandardCharacteristics'
    ];

    /**
     * Array of attributes to getter functions (for serialization of requests)
     *
     * @var string[]
     */
    protected static $getters = [
        'weight_uom' => 'getWeightUom',
        'weight' => 'getWeight',
        'dimensions_uom' => 'getDimensionsUom',
        'length' => 'getLength',
        'height' => 'getHeight',
        'width' => 'getWidth',
        'girth' => 'getGirth',
        'has_nonstandard_characteristics' => 'getHasNonstandardCharacteristics'
    ];

    /**
     * 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 WEIGHT_UOM_LB = 'lb';
    const DIMENSIONS_UOM_IN = 'in';

    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getWeightUomAllowableValues()
    {
        return [
            self::WEIGHT_UOM_LB,
        ];
    }
    /**
     * Gets allowable values of the enum
     *
     * @return string[]
     */
    public function getDimensionsUomAllowableValues()
    {
        return [
            self::DIMENSIONS_UOM_IN,
        ];
    }

    /**
     * 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['weight_uom'] = isset($data['weight_uom']) ? $data['weight_uom'] : 'lb';
        $this->container['weight'] = isset($data['weight']) ? $data['weight'] : null;
        $this->container['dimensions_uom'] = isset($data['dimensions_uom']) ? $data['dimensions_uom'] : 'in';
        $this->container['length'] = isset($data['length']) ? $data['length'] : null;
        $this->container['height'] = isset($data['height']) ? $data['height'] : null;
        $this->container['width'] = isset($data['width']) ? $data['width'] : null;
        $this->container['girth'] = isset($data['girth']) ? $data['girth'] : null;
        $this->container['has_nonstandard_characteristics'] = isset($data['has_nonstandard_characteristics']) ? $data['has_nonstandard_characteristics'] : false;
    }

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

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

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

        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 weight_uom
     *
     * @return string
     */
    public function getWeightUom()
    {
        return $this->container['weight_uom'];
    }

    /**
     * Sets weight_uom
     *
     * @param string $weight_uom Weight Unit of Measurement   * lb - Pounds
     *
     * @return $this
     */
    public function setWeightUom($weight_uom)
    {
        $allowedValues = $this->getWeightUomAllowableValues();
        if (!is_null($weight_uom) && !in_array($weight_uom, $allowedValues, true)) {
            throw new \InvalidArgumentException(
                sprintf(
                    "Invalid value for 'weight_uom', must be one of '%s'",
                    implode("', '", $allowedValues)
                )
            );
        }
        $this->container['weight_uom'] = $weight_uom;

        return $this;
    }

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

    /**
     * Sets weight
     *
     * @param float $weight The package weight, in weightUOM (Unit Of Measure). Items must weigh 70 pounds (1120 ounces) or less.
     *
     * @return $this
     */
    public function setWeight($weight)
    {
        $this->container['weight'] = $weight;

        return $this;
    }

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

    /**
     * Sets dimensions_uom
     *
     * @param string $dimensions_uom Dimensions unit of measure * in - Inches
     *
     * @return $this
     */
    public function setDimensionsUom($dimensions_uom)
    {
        $allowedValues = $this->getDimensionsUomAllowableValues();
        if (!is_null($dimensions_uom) && !in_array($dimensions_uom, $allowedValues, true)) {
            throw new \InvalidArgumentException(
                sprintf(
                    "Invalid value for 'dimensions_uom', must be one of '%s'",
                    implode("', '", $allowedValues)
                )
            );
        }
        $this->container['dimensions_uom'] = $dimensions_uom;

        return $this;
    }

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

    /**
     * Sets length
     *
     * @param float $length The length of the container, in dimensionsUOM. If partial dimensions are provided, an error response will return. Length, Width, and Height are required for accurate pricing of a rectangular package when any dimension of the item exceeds 12 inches. Girth is required only for a non-rectangular package in addition to Length, Width, and Height when any dimension of the package exceeds 12 inches. For rectangular packages, the Girth dimension must be left blank as this dimension is to only be used for non-rectangular packages.
     *
     * @return $this
     */
    public function setLength($length)
    {
        $this->container['length'] = $length;

        return $this;
    }

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

    /**
     * Sets height
     *
     * @param float $height The height of the container, in dimensionsUOM. If partial dimensions are provided, an error response will return. Length, Width, and Height are required for accurate pricing of a rectangular package when any dimension of the item exceeds 12 inches. Girth is required only for a non-rectangular package in addition to Length, Width, and Height when any dimension of the package exceeds 12 inches. For rectangular packages, the Girth dimension must be left blank as this dimension is to only be used for non-rectangular packages.
     *
     * @return $this
     */
    public function setHeight($height)
    {
        $this->container['height'] = $height;

        return $this;
    }

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

    /**
     * Sets width
     *
     * @param float $width The width of the container, in dimensionsUOM. If partial dimensions are provided, an error response will return. Length, Width, and Height are required for accurate pricing of a rectangular package when any dimension of the item exceeds 12 inches. Girth is required only for a non-rectangular package in addition to Length, Width, and Height when any dimension of the package exceeds 12 inches. For rectangular packages, the Girth dimension must be left blank as this dimension is to only be used for non- rectangular packages.
     *
     * @return $this
     */
    public function setWidth($width)
    {
        $this->container['width'] = $width;

        return $this;
    }

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

    /**
     * Sets girth
     *
     * @param float $girth The girth of the container, in dimensionsUOM. If partial dimensions are provided, an error response will return. Length, Width, Height are required for accurate pricing of a rectangular package when any dimension of the item exceeds 12 inches. In addition, Girth is required only for a non- rectangular package in addition to Length, Width, Height when any dimension of the package exceeds 12 inches. For rectangular packages, the Girth dimension must be left blank as this dimension is to only be used for non- rectangular packages.
     *
     * @return $this
     */
    public function setGirth($girth)
    {
        $this->container['girth'] = $girth;

        return $this;
    }

    /**
     * Gets has_nonstandard_characteristics
     *
     * @return bool
     */
    public function getHasNonstandardCharacteristics()
    {
        return $this->container['has_nonstandard_characteristics'];
    }

    /**
     * Sets has_nonstandard_characteristics
     *
     * @param bool $has_nonstandard_characteristics Package is nonstandard. Nonstandard packages include cylindrical tubes and rolls, certain high-density items, cartons containing more than 24 ounces of liquids in one or more glass containers, cartons containing 1 gallon or more of liquid in metal or plastic containers, and items in [201.7.6.2](https://pe.usps.com/text/dmm300/201.htm#7.6.2).
     *
     * @return $this
     */
    public function setHasNonstandardCharacteristics($has_nonstandard_characteristics)
    {
        $this->container['has_nonstandard_characteristics'] = $has_nonstandard_characteristics;

        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));
    }
}
