<?php

namespace common\components\artboximage;

use Yii;
use yii\base\Object;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
use yii\web\HttpException;

class ArtboxImageHelper extends Object {
    /** @var  ArtboxImage $imageDriver */
    private static $imageDriver;
    private static $presets;

    public function getDriver() {
        if (empty(self::$imageDriver)) {
            self::$imageDriver = Yii::$app->artboximage;
        }
        return self::$imageDriver;
    }

    public function getPreset($preset) {
        if (empty(self::$presets)) {
            self::$presets = self::getDriver()->presets;
        }
        return empty(self::$presets[$preset]) ? null : self::$presets[$preset];
    }

    public static function getImage($file, $preset, $imgOptions = []) {
        return Html::img(self::getImageSrc($file, $preset), $imgOptions);
    }

    public static function getImageSrc($file, $preset, $preset_alias = null) {
        if (is_string($preset)) {
            $preset_alias = $preset;
            $preset = self::getPreset($preset);
        }
        if (empty($preset) || empty($preset_alias)) {
            return $file;
        }
        $filePath = self::getPathFromUrl($file);
        if (!file_exists($filePath) || !preg_match('#^(.*)\.(' . self::getExtensionsRegexp() . ')$#', $file, $matches)) {
            return $file;
        }
        return self::getPresetUrl($filePath, $preset, $preset_alias);
    }

    public static function fileinputWidget($model, $modelField, $formField = 'fileUpload', $multiple = false) {
        return Yii::$app->artboximage->fileinputWidget($model, $modelField, $formField, $multiple);
    }

    private static function getPathFromUrl($url) {
        return substr_replace($url, self::getDriver()->rootPath, 0, strlen(self::getDriver()->rootUrl));
    }

    private static function getUrlFromPath($path) {
        return substr_replace($path, self::getDriver()->rootUrl, 0, strlen(self::getDriver()->rootPath));
    }

    private static function getPresetUrl($filePath, $preset, $preset_alias) {
        $pathinfo = pathinfo($filePath);
        $presetPath = $pathinfo['dirname'] .'/styles/'. strtolower($preset_alias);
        $presetFilePath = $presetPath .'/'. $pathinfo['basename'];
        $presetUrl = self::getUrlFromPath($presetFilePath);
        if (file_exists($presetFilePath)) {
            return $presetUrl;
        }
        if (!file_exists($presetPath)) {
            @mkdir($presetPath, 0777, true);
        }
        $output = self::createPresetImage($filePath, $preset, $preset_alias);
        if ( !empty($output) ) {
            $f = fopen($presetFilePath, 'w');
            fwrite($f, $output);
            fclose($f);
            return $presetUrl;
        }
        return false;
    }

    private static function createPresetImage($filePath, $preset, $preset_alias)
    {
        $image = self::getDriver()->load($filePath);
        foreach ($preset as $action => $data) {
            switch($action) {
                case 'resize':
                    $image->resize($data['width'], $data['height'], @$data['master']);
                    break;
                case 'crop':
                    $image->crop($data['width'], $data['height'], @$data['offset_x'], @$data['offset_y']);
                    break;
                case 'flip':
                    $image->flip(@$data['direction']);
                    break;
                default:
                    break;
            }
        }
        return $image->render();
    }

    /**
     * Get extensions regexp
     * @return string regexp
     */
    private function getExtensionsRegexp()
    {
        $keys = array_keys(self::getDriver()->extensions);
        return '(?i)' . join('|', $keys);
    }

    /**
     * Get size from suffix
     * @param string $suffix
     * @return string size
     */
    private function getSizeFromSuffix($suffix)
    {
        return array_search($suffix, $this->getSizeSuffixes());
    }

    /**
     * Get suffix from size
     * @param string $size
     * @return string suffix
     */
    private function getSufixFromSize($size)
    {
        return ArrayHelper::getValue($this->getSizeSuffixes(), $size);
    }

    private function getSizeSuffixes()
    {
        $suffixes = [];
        foreach ($this->sizes as $size => $sizeConf) {
            $suffixes[$size] = ArrayHelper::getValue($this->sizeSuffixes, $size, $this->defaultSizeSuffix . $size);
        }
        return $suffixes;
    }
}