<?php

/*
 * The MIT License
 *
 * Copyright 2019 Blobt.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

namespace blobt\grid;

use Closure;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use yii\data\ArrayDataProvider;
use yii\db\ActiveQueryInterface;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\helpers\Inflector;

/**
 * 
 * 
 * @author Blobt
 * @email 380255922@qq.com
 * @created Aug 13, 2019
 */
class DataColumn extends Column {

    /**
     * @var string 本列需要显示的模型属性值,
     * 如果设置了value,则会显示value。
     */
    public $attribute;

    /**
     * @var string 列首的label。如果不设置,则会显示attribute关联的label
     */
    public $label;

    /**
     * @var bool 是否需要html转义
     */
    public $encodeLabel = true;

    /**
     * @var string|Closure 字符串或匿名函数.
     */
    public $value;

    /**
     * @var string|array|Closure 每个数据模型的值应以哪种格式显示(例如“raw”`、“text”`、“html”`,`[date','php:y-m-d']`)。
     * 默认格式为“文本”
     */
    public $format = 'text';

    /**
     * @var bool 有时候我们记录数据时候,使用了整数值来代替字符,当此属性被设置成true时候,
     * 会视图找到数值对应的字符,并显示出来
     */
    public $showConstText = false;

    /**
     * @var bool 是否开始排序
     */
    public $enableSorting = true;

    /**
     * @var bool 排序a标签的html属性
     */
    public $sortLinkOptions = [];

    /**
     * @var bool 筛选表单单
     */
    public $filter;

    /**
     * 初始化参数
     */
    public function init() {
        parent::init();
    }

    /**
     * 渲染头单元.
     */
    public function renderHeaderCell() {
        return Html::tag('th', $this->renderHeaderCellContent(), $this->headerOptions);
    }

    /**
     * {@inheritdoc}
     */
    protected function renderHeaderCellContent() {
        if ($this->header !== null || $this->label === null && $this->attribute === null) {
            return parent::renderHeaderCellContent();
        }

        $label = $this->getHeaderCellLabel();
        if ($this->encodeLabel) {
            $label = Html::encode($label);
        }

        if ($this->attribute !== null && $this->enableSorting &&
                ($sort = $this->grid->dataProvider->getSort()) !== false && $sort->hasAttribute($this->attribute)) {
            return $sort->link($this->attribute, array_merge($this->sortLinkOptions, ['label' => $label]));
        }

        return $label;
    }

    /**
     * {@inheritdoc]
     */
    protected function getHeaderCellLabel() {
        $provider = $this->grid->dataProvider;

        if ($this->label === null) {
            if ($provider instanceof ActiveDataProvider && $provider->query instanceof ActiveQueryInterface) {
                /* @var $modelClass Model */
                $modelClass = $provider->query->modelClass;
                $model = $modelClass::instance();
                $label = $model->getAttributeLabel($this->attribute);
            } elseif ($provider instanceof ArrayDataProvider && $provider->modelClass !== null) {
                /* @var $modelClass Model */
                $modelClass = $provider->modelClass;
                $model = $modelClass::instance();
                $label = $model->getAttributeLabel($this->attribute);
            } else {
                $models = $provider->getModels();
                if (($model = reset($models)) instanceof Model) {
                    /* @var $model Model */
                    $label = $model->getAttributeLabel($this->attribute);
                } else {
                    $label = Inflector::camel2words($this->attribute);
                }
            }
        } else {
            $label = $this->label;
        }

        return $label;
    }

    /**
     * 返回单元格值
     * @param mixed $model
     * @param mixed $key 模型ID
     * @param int $index 行号
     * @return string 
     */
    public function getDataCellValue($model, $key, $index) {
        if ($this->value !== null) {
            if (is_string($this->value)) {
                return ArrayHelper::getValue($model, $this->value);
            }

            return call_user_func($this->value, $model, $key, $index, $this);
        } elseif ($this->attribute !== null) {
            $val = ArrayHelper::getValue($model, $this->attribute);
            if ($this->showConstText) {
                $constArrKey = Inflector::variablize($this->attribute, '_');
                if (isset($model::$$constArrKey)) {
                    $val = $model::$$constArrKey[$val];
                }
            }
            return $val;
        }

        return null;
    }

    /**
     * {@inheritdoc}
     */
    protected function renderDataCellContent($model, $key, $index) {
        if ($this->content === null) {
            return $this->grid->formatter->format($this->getDataCellValue($model, $key, $index), $this->format);
        }

        return parent::renderDataCellContent($model, $key, $index);
    }

}