<?php
require_once LIB_ROOT . '/dataframe/hypothesis/onesample.php';
require_once LIB_ROOT . '/dataframe/checkdata.php';
require_once LIB_ROOT . '/dataframe/validatedata.php';

/* 单样本t */
class OnesampleMethod
{
    /* Method name 分析方法内部名称 */
    public static $name = 'Onesample';

    /* Method settings 方法设置参数定义 */
    public static $settings = array();

    /* Diagram config 图表配置项 */
    public static $config = array();

    /* Callback for basic hypothesis method 基本量统计计算回调函数 */
    public static function func($dataframe, $settings)
    {
        global $dasLang;
        global $lang;
        global $app;

        $type       = 'number';
        $dataDesc   = $settings['data'];
        $vars       = $settings['sampleCol'];
        $sampleNum  = $settings['sampleNum'];
        $mean       = $settings['mean'];
        $sd         = $settings['sd'];
        $hypo       = $settings['hypo'];
        $hypoMean   = $settings['hypoMean'];
        $confidence = $settings['confidence'];
        $alterHypo  = $settings['alternativeHypo']; // $lang->onesample->alterHypoEnum, option value: lt|ne|gt

        $onesample = new onesample($dataframe);

        if($dataDesc == 'sampleData')
        {
            $check = new checkData();
            $check->setDataList($dataframe->colsData($vars), $dataframe->colsName($vars), self::$settings['sampleCol']['validate']);

            $checkRes = $check->check();
            if(is_string($checkRes)) return ValidateData::result($checkRes);

            $judgeData = $dataframe->cols($vars, $type);
            $validLine = array();
            foreach($judgeData as $var => $dataTmp)
            {
                if($dataTmp->haveString) return array('result' => 'fail', 'message' => sprintf($dasLang->onesample->errorString, $dataframe->columns[$var]));
            }
        }

        $sampleResult = new stdclass();
        $sampleResult->type  = 'table';
        $sampleResult->title = $dasLang->onesample->sampleText;
        $sampleResult->data  = array();

        $hypoResult = new stdclass();
        $hypoResult->type  = 'table';
        $hypoResult->title = $dasLang->onesample->hypoText;
        $hypoResult->data = array();

        $sampleData = array();
        $hypoData   = array();
        if($dataDesc == 'sampleData')
        {
            $varsCount = count($vars);
            foreach($vars as $index => $var)
            {
                $sliceDF   = $dataframe->sliceDataframe($dataframe, $var, 'any');
                $data      = $sliceDF->col($var, $type);
                $sampleNum = $data->numCount;
                $μ         = $onesample->bar($data->notNull());
                $σ         = $onesample->sigma($data->notNull());
                $stDev     = $onesample->stDev($σ, $sampleNum);
                $CI        = $onesample->CI($μ, $σ,$sampleNum, $confidence, $alterHypo);

                if($varsCount >= 2)$sampleData[$index][] = $dataframe->columns[$var];
                $sampleData[$index][] = $sampleNum;
                $sampleData[$index][] = $μ;
                $sampleData[$index][] = $σ;
                $sampleData[$index][] = $stDev;
                $sampleData[$index][] = $onesample->getCIValue($CI, $alterHypo);

                if($hypo == 'true')
                {
                    $t = $onesample->T($μ, $σ, $sampleNum, $hypoMean);
                    $p = $onesample->P($t, $sampleNum, $alterHypo);

                    if($varsCount >= 2) $hypoData[$index][] = $dataframe->columns[$var];
                    $hypoData[$index][] = $t;
                    $hypoData[$index][] = $p;
                }
            }

            $sampleResult->data['data']    = $sampleData;
            $sampleColumns                 = $onesample->createColumns($dasLang->onesample, $varsCount < 2 ? $dasLang->onesample->sampleDataColumns : array_merge($dasLang->onesample->addColumn, $dasLang->onesample->sampleDataColumns));
            $sampleColumns[]               = array('label' => $onesample->getCITitle($dasLang->onesample, $confidence, $app->getClientLang(), $alterHypo), 'type' => 'number');
            $sampleResult->data['columns'] = $sampleColumns;

            $hypoResult->data['data']    = $hypoData;
            $hypoResult->data['columns'] = $onesample->createColumns($dasLang->onesample, $varsCount < 2 ? $dasLang->onesample->hypoDataColumns : array_merge($dasLang->onesample->addColumn, $dasLang->onesample->hypoDataColumns));
            $hypoResult->desc            = $onesample->getDesc($hypoMean, $alterHypo, $dasLang->onesample->testDesc);

        }
        else
        {
            $μ    = $mean;
            $σ    = $sd;
            $stDev = $onesample->stDev($σ, $sampleNum);
            $CI    = $onesample->CI($μ, $σ,$sampleNum, $confidence, $alterHypo);

            $sampleData[0][] = $sampleNum;
            $sampleData[0][] = $μ;
            $sampleData[0][] = $σ;
            $sampleData[0][] = $stDev;
            $sampleData[0][] = $onesample->getCIValue($CI, $alterHypo);

            if($hypo == 'true')
            {
                $t = $onesample->T($μ, $σ, $sampleNum, $hypoMean);
                $p = $onesample->P($t, $sampleNum, $alterHypo);

                $hypoData[0][] = $t;
                $hypoData[0][] = $p;
            }

            $sampleResult->data['data']    = $sampleData;
            $sampleColumns                 = $onesample->createColumns($dasLang->onesample, $dasLang->onesample->sampleDataColumns);
            $sampleColumns[]               = array('label' => $onesample->getCITitle($dasLang->onesample, $confidence, $app->getClientLang(), $alterHypo), 'type' => 'number');
            $sampleResult->data['columns'] = $sampleColumns;

            $hypoResult->data['data']    = $hypoData;
            $hypoResult->data['columns'] = $onesample->createColumns($dasLang->onesample, $dasLang->onesample->hypoDataColumns);
            $hypoResult->desc            = $onesample->getDesc($hypoMean, $alterHypo, $dasLang->onesample->testDesc);
        }

        $allResult = array();
        $allResult[] = $sampleResult;
        if($hypo == 'true') $allResult[] = $hypoResult;

        return $allResult;
    }

    /**
     * Get settings.
     *
     * @param object $lang
     * @access public
     * @return object
     */
    public static function getSettings()
    {
        global $dasLang;
        $lang = $dasLang->onesample;

        /* Basic settings */
        self::$settings['data']            = array('name' => 'data',            'label' => $lang->data);
        self::$settings['sampleCol']       = array('name' => 'sampleCol',       'label' => $lang->sampleCol,       'required' => true);
        self::$settings['sampleNum']       = array('name' => 'sampleNum',       'label' => $lang->sampleNum,       'required' => true);
        self::$settings['mean']            = array('name' => 'mean',            'label' => $lang->mean,            'required' => true);
        self::$settings['sd']              = array('name' => 'sd',              'label' => $lang->sd,              'required' => true);
        self::$settings['confidence']      = array('name' => 'confidence',      'label' => $lang->confidence,      'required' => true);
        self::$settings['hypo']            = array('name' => 'hypo',            'label' => $lang->hypo);
        self::$settings['hypoMean']        = array('name' => 'hypoMean',        'label' => $lang->hypoMean,        'required' => true);
        self::$settings['alternativeHypo'] = array('name' => 'alternativeHypo', 'label' => $lang->alternativeHypo, 'required' => true);

        /* Type settings */
        self::$settings['data']            += array('type' => 'enum', 'enumOptions' => array('sampleData' => $lang->sampleData, 'summary' => $lang->summary), 'defaultValue' => 'sampleData');
        self::$settings['sampleCol']       += array('type' => 'list', 'listType' => 'column', 'columnType' => 'number');
        self::$settings['sampleNum']       += array('type' => 'number', 'columnType' => 'number');
        self::$settings['mean']            += array('type' => 'number');
        self::$settings['sd']              += array('type' => 'number');
        self::$settings['confidence']      += array('type' => 'number', 'defaultValue' => 95);
        self::$settings['hypo']            += array('type' => 'enum', 'enumOptions' => $lang->hypoEnum, 'columnType' => 'any', 'defaultValue' => 'false');
        self::$settings['hypoMean']        += array('type' => 'number', 'defaultValue' => 0);
        self::$settings['alternativeHypo'] += array('type' => 'enum', 'ui' => 'select', 'enumOptions' => $lang->alterHypoEnum, 'defaultValue' => 'ne');

        /* Limit settings */
        self::$settings['sampleCol']       += array('conditions' => array('data' => 'sampleData'));
        self::$settings['sampleNum']       += array('conditions' => array('data' => 'summary'), 'pattern' => "/^[1-9]([0-9]{1,7})?$/", 'min' => 1, 'max' => 100000000, 'error' => $lang->errorSample);
        self::$settings['mean']            += array('conditions' => array('data' => 'summary'), 'pattern' => "/^[\+\-]?[\d]+(\.[\d]+)?$/", 'min' => -99999999, 'max' => 99999999, 'error' => $lang->errorMean);
        self::$settings['sd']              += array('conditions' => array('data' => 'summary'), 'pattern' => "/^([1-9]\d*)(\.[\d]+)?$|^0\.\d+?$/", 'max' => 99999999, 'error' => $lang->errorSD);
        self::$settings['confidence']      += array('pattern' => "/^[\+\-]?[\d]+(\.[\d]+)?$/", 'error' => $lang->errorConfidence, 'min' => 0.0001, 'max' => 99.9999);
        self::$settings['hypoMean']        += array('conditions' => array('hypo' => 'true'), 'pattern' => "/^[\+\-]?[\d]+(\.[\d]+)?$/", 'error' => $lang->errorHypoMean, 'min' => -99999999.01, 'max' => 99999998.99);
        self::$settings['alternativeHypo'] += array('conditions' => array('hypo' => 'true'));

        /* More settings */
        self::$settings['hypo']            += array('paramType' => 'more');
        self::$settings['hypoMean']        += array('paramType' => 'more');
        self::$settings['confidence']      += array('paramType' => 'more');
        self::$settings['alternativeHypo'] += array('paramType' => 'more');

        /* Data validate */
        self::$settings['sampleCol'] += array('validate' => array('continuous', 'number', 'N >= 2', 'notCommon'));

        return self::$settings;
    }

    /**
     * Get config.
     *
     * @access public
     * @return object
     */
    public static function getConfig()
    {
        global $dasLang;
        $lang = $dasLang->config;

        //return self::$config;
    }
}
