<?php

namespace Sabberworm\CSS\CSSList;

use Sabberworm\CSS\RuleSet\DeclarationBlock;
use Sabberworm\CSS\RuleSet\RuleSet;
use Sabberworm\CSS\Property\Selector;
use Sabberworm\CSS\Rule\Rule;
use Sabberworm\CSS\Value\ValueList;
use Sabberworm\CSS\Value\CSSFunction;

/**
 * A CSSList is the most generic container available. Its contents include RuleSet as well as other CSSList objects.
 * Also, it may contain Import and Charset objects stemming from @-rules.
 */
abstract class CSSList {

    protected $aContents;

    public function __construct() {
        $this->aContents = array();
    }

    public function append($oItem) {
        $this->aContents[] = $oItem;
    }

    /**
     * Removes an item from the CSS list.
     * @param RuleSet|Import|Charset|CSSList $oItemToRemove May be a RuleSet (most likely a DeclarationBlock), a Import, a Charset or another CSSList (most likely a MediaQuery)
     */
    public function remove($oItemToRemove) {
        $iKey = array_search($oItemToRemove, $this->aContents, true);
        if ($iKey !== false) {
            unset($this->aContents[$iKey]);
        }
    }

    public function removeDeclarationBlockBySelector($mSelector, $bRemoveAll = false) {
        if ($mSelector instanceof DeclarationBlock) {
            $mSelector = $mSelector->getSelectors();
        }
        if (!is_array($mSelector)) {
            $mSelector = explode(',', $mSelector);
        }
        foreach ($mSelector as $iKey => &$mSel) {
            if (!($mSel instanceof Selector)) {
                $mSel = new Selector($mSel);
            }
        }
        foreach ($this->aContents as $iKey => $mItem) {
            if (!($mItem instanceof DeclarationBlock)) {
                continue;
            }
            if ($mItem->getSelectors() == $mSelector) {
                unset($this->aContents[$iKey]);
                if (!$bRemoveAll) {
                    return;
                }
            }
        }
    }

    public function __toString() {
        $sResult = '';
        foreach ($this->aContents as $oContent) {
            $sResult .= $oContent->__toString();
        }
        return $sResult;
    }

    public function getContents() {
        return $this->aContents;
    }
}
