<?php

namespace loyalsoft;

/**
 * Description of Ins_Accumulate
 * 累充功能
 * @author gwang
 */
class Ins_Accumulate {

    /**
     * @var int 内部数据 |31~16(bitflag)|15~0(tsDay_begin)|
     */
    private $data = 0;
    private static $amountArr = array(6, 38, 98);
    private static $dayArr = array(1, 2, 3);

    /**
     * 计算定位
     * @staticvar array $amountArr
     * @staticvar array $dayArr
     * @param type $amount
     * @param type $day
     * @return int
     */
    private static function getIndex($amount, $day): int {
        my_Assert(in_array($amount, self::$amountArr), "累充金额错误!");
        my_Assert(in_array($day, self::$dayArr), "累充奖励天数错误!");
        $x = array_search($amount, self::$amountArr);
        $y = array_search($day, self::$dayArr);
        $i = $x * 3 + $y;            # 6-1,6-2,6-3,38-1,38-2,38-3,98-1,98-2,98-3
        return 16 + $i;
    }

    /**
     * @param int $amount 金额(6,38,98)
     * @param int $day    第几天(1,2,3)
     * @return bool 判断指定礼包是否已领取
     */
    public function IsDrawed($amount, $day): bool {
        return Bits::GetBitValue($this->data, self::getIndex($amount, $day));
    }

    /**
     * 设置已领取指定礼包
     * @param int $amount 金额(6,38,98)
     * @param int $day    第几天(1,2,3)
     * @return int 最新data
     */
    public function SetDrawd($amount, $day): int {
        return Bits::SetBitValue($this->data, self::getIndex($amount, $day), true);
    }

    /**
     * 设置开始时间(tsDay)
     * @param type $tsDay
     * @return int 内部data值
     */
    public function SetBeginDay($tsDay): int {
        $this->data &= -65535;
        $this->data |= $tsDay;
        return $this->data;
    }

    /**
     * @return int 开始于哪天
     */
    public function BeginDay(): int {
        return $this->data & 65535;       # 低16位保存开始时间
    }

    /**
     * @return int
     */
    public function Day() {
        return tsDay() - $this->BeginDay() + 1;
    }

    /**
     * @return int 结束于哪天
     */
    public function EndDay(): int {
        return $this->BeginDay() + 3;
    }

    /**
     * 构造函数
     * @param type $intVal
     */
    public function __construct($intVal = 0) {
        my_Assert($intVal > 0, "咱不接受负数参数!");                              # 防御: 不会出现负值
        $this->data = $intVal;
    }

    /**
     * @return int 实际的数据
     */
    public function Data(): int {
        return $this->data;
    }

    /**
     * 方便调试打印
     * @return string
     */
    public function __toString() {
        $nl = (php_sapi_name() === 'cli') ? PHP_EOL : "<br/>";
        $str = "" . __CLASS__ . $nl;
        foreach (self::$amountArr as $amt) {
            foreach (self::$dayArr as $d) {
                $str .= "($amt,$d) := " . ($this->IsDrawed($amt, $d) ? "true" : "false") . $nl;
            }
        }
        $str .= "BeginDay := {$this->BeginDay()}";
        return $str;
    }

}
