<?php
    
    namespace common\components\artboximage;
    
    use Yii;
    use yii\base\Object;
    use yii\helpers\ArrayHelper;
    use yii\helpers\Html;
    
    class ArtboxImageHelper extends Object
    {
        
        /** @var  ArtboxImage $imageDriver */
        private static $imageDriver;
        
        private static $presets;
        
        public static function getDriver()
        {
            if(empty( self::$imageDriver )) {
                self::$imageDriver = Yii::$app->artboximage;
            }
            return self::$imageDriver;
        }
        
        public static 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 = [])
        {
            $preset_alias = is_array($preset) ? array_keys($preset)[ 0 ] : NULL;
            return Html::img(self::getImageSrc($file, $preset, $preset_alias), $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':
                        $width = empty( $data[ 'width' ] ) ? NULL : $data[ 'width' ];
                        $height = empty( $data[ 'height' ] ) ? NULL : $data[ 'height' ];
                        $master = empty( $data[ 'master' ] ) ? NULL : $data[ 'master' ];
                        $image->resize($width, $height, $master);
                        break;
                    case 'flip':
                        $image->flip(@$data[ 'direction' ]);
                        break;
                    default:
                        break;
                }
            }
            return $image->render();
        }
        
        /**
         * Get extensions regexp
         * @return string regexp
         */
        private static 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;
        }
    }