<?php

namespace WpieFw\Framework\Patterns\Iterator;

use WpieFw\Framework\Patterns\Iterator\WpieCollectionInterface;

if( ! defined( 'ABSPATH' ) ) exit;

abstract class WpieCollection implements WpieCollectionInterface
{
	/**
	 * The collection
	 *
	 * @var array
	 */
	protected $collection = [];

	/**
	 * Constructor
	 *
	 * @param array $collection
	 */
	public function __construct( array $collection = [] )
	{
		$this->setMultiple( $collection );
	}

	/**
	 * {@inheritDoc}
	 * @see \WpieFw\Framework\Patterns\Iterator\WpieCollectionInterface::setMultiple()
	 */
	public function setMultiple( array $collection = []  )
	{
		if( !empty( $collection ) ) {
			foreach ( $collection as $k => $v ) {
				$this->offsetSet( $k, $v);
			}
		}

		return $this;
	}

	/**
	 * Facilitate an iterator to loop through the collection
	 *
	 * @return \Traversable
	 */
	public function getIterator (): \Traversable
	{
		return new \ArrayIterator( $this->collection );
	}


	/**
	 * Get collection except given offset
	 *
	 * @param mixed $offset
	 *
	 * @return array
	 */
	public function getExcept( $offset )
	{
		$collection = [];

		foreach ( $this as $key => $value ) {
			if( $offset !== $key ) {
				$collection[$key] = $value;
			}
		}

		return $collection;
	}

	/**
	 * @param string $offset
	 *
	 * @return bool
	 */
	public function offsetExists( $offset ): bool
	{
		if( isset( $this->collection[$offset] ) ) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @param string $offset
	 *
	 * @return mixed
	 */
	#[\ReturnTypeWillChange]
	public function offsetGet( $offset )
	{
		if( isset( $this->collection[$offset] ) ) {
			return $this->collection[$offset];
		}
	}

	/**
	 * Shortcut to offsetGet
	 *
	 * @param mixed $offset
	 * @return mixed
	 */
	public function get( $offset )
	{
		return $this->offsetGet( $offset );
	}

	/**
	 * @param mixed $offset
	 * @param mixed $value
	 *
	 * @return void
	 */
	public function offsetSet( $offset, $value ): void
	{
		$this->collection[$offset] = $value;
	}

	/**
	 * Shortcut to offsetSet
	 *
	 * @param mixed $offset
	 * @param mixed $value
	 *
	 * @return void
	 */
	public function set( $offset, $value )
	{
		$this->offsetSet( $offset, $value );
	}

	/**
	 * @param string $offset
	 *
	 * @return void
	 */
	public function offsetUnset( $offset ): void
	{
		if( isset( $this->collection[$offset] ) ) {
			unset( $this->collection[$offset] );
		}
	}

	/**
	 * Determine if collection has items
	 *
	 * @return boolean
	 */
	public function hasCollection()
	{
		return ( 0 < count( $this->collection ) ) ? true : false;
	}
}