<?php
defined( 'ABSPATH' ) or exit;   // show a blank page if try to access this file directly

require_once( EWZ_PLUGIN_DIR . "classes/ewz-base.php");

class Ewz_Settings extends Ewz_Base {
   /**
    * @var array<string,string> $qual_opts
    */
    /** @phpstan-ignore-next-line */
    protected static $qual_opts =  array( '-1'=>'Use Wordpress Default', '100'=>'100%', '98'=>'98%', '95'=>'95%', '90'=>'90%', '85'=>'85%', '80'=>'80%', '70'=>'70%','60'=>'60%','50'=>'50%','40'=>'40%','30'=>'30%','20'=>'20%','10'=>'10%','5'=>'5%');

    // NB: when adding new options, remember to add them to the validation class and to the delete list in uninstall.php
   /**
    * @var  array<string, array{'type':string,'params':array<mixed>,'def':mixed,'desc':string}> $defaults
    */
    protected static $defaults = array(

        'del_imgs_on_uninst' => array( 'type'   => 'boolean',
                                       'params' => array(),
                                       'def'    => true,
                                       'desc'   => "When uninstalling EntryWizard, delete all uploaded images, too.<br>--- i.e. delete the uploads/ewz_img_uploads folder and all its contents. <br>Note that <u>uninstalling always deletes all your other entrywizard data</u>.<br><br>Copies created by attaching images to pages are <u>not</u> removed when uninstalling. " ),

        // ************ NB: when adding new options, remember to add them to the validation class and to the delete list in uninstall.php

        'upload_closed_txt'  => array( 'type'   => 'string',
                                       'params' => array( 'maxlen' => 120 , 'lines' => 1),
                                       'def'    => 'Sorry, this form is not currently open for uploads.',
                                       'desc'   => 'Text to display to user when a webform is not open.'),

        'show_title_if_closed' => array( 'type' =>  'boolean',
                                       'params' => array(),
                                       'def'    => true,
                                       'desc'   => 'Display the title to the user when a webform is not open.'),

        'curr_stored_txt'    => array( 'type'   => 'string',
                                       'params' => array( 'maxlen' => 80, 'lines' => 1 ),
                                       'def'    => 'Currently stored on the server for ',
                                       'desc'   => 'Text to display when there are stored images.<br> --- Appears at the top of the upload form, followed by the user name.'),

      'spec_char_replace'    => array( 'type'   => 'select',
                                       'params' =>  array( 'opts' => array( '_'=>'_', '-'=>'-', 'X'=>'X', 'x'=>'x' ) ),
                                       'def'    => '_',
                                       'desc'   => 'Character used to replace spaces or other disallowed characters in filenames.<br> --- To make the filename acceptable on most hosting systems, "disallowed characters" are any characters other than letters, digits, underscores or dashes.'),

      'terminal_underscore'   => array( 'type'   => 'boolean',
                                       'params' =>  array(),
                                       'def'    =>  true,
                                       'desc'   => 'Insert the above replacement character after a terminal digit in the filename. This helps to separate it from the digits wordpress may add to make the filename unique in its folder.'),

                 'margin'    => array( 'type'   => 'select',
                                       'params' => array( 'opts' => array('0'=>'0','1'=>'1','2'=>'2','3'=>'3','4'=>'4','5'=>'5','10'=>'10','20'=>'20','50'=>'50',
                                                                          '100'=>'100','200'=>'200','500'=>'500','800'=>'800' )),
                                       'def'    => '0',
                                       'desc'   => 'Number of pixels of leeway allowed when "Image must be as large as possible" is set.<br>If larger values are used, this could be an alternative to setting the minimum longest dimension, but it does apply to all layouts.'),

    // ************ NB: when adding new options, remember to add them to the validation class and to the delete list in uninstall.php
        'attach_img_size'   => array( 'type'   => 'select',
                                       'params' => array(),
                                       'def'    => 'large',
                                       'desc'   => 'Default size to use when attaching uploaded images to an existing page. (May be overridden for a particular webform when attaching.)'),

        'attach_img_comment' => array( 'type'   => 'boolean',
                                       'params' => array(),
                                       'def'    => false,
                                       'desc'   => 'By default, allow comments when attaching uploaded images to an existing page. (May be overridden for a particular webform when attaching.)'),
        // NB: using '0' to mean "use the wordpress default" -- be careful
        'attach_jpeg_qual'   => array( 'type'   => 'select',
                                       'params' => array(),
                                       'def'    => '-1',
                                       'desc'   => 'Default jpeg quality to use when attaching uploaded images to an existing page. (May be overridden for a particular webform when attaching.)<br> --- In Wordpress 3.5, the default is 82%.'),
        'webform_alias' => array( 'type' => 'string',
                                  'params' => array( 'maxlen' => 40, 'lines' => 1 ),
                                  'def'    => 'Webform',
                                  'desc'   => 'The word "Webform" is used throughout EntryWizard to refer to the upload form generated by the shortcode.<br>In spreadsheet and table headers, you may wish to see something more meaningful for your installation.  Instead of the word "Webform",  use: ' ),

        'ss_usr_labels' => array( 'type' => 'boolean',
                                  'params' => array( ),
                                  'def'    => false,
                                  'desc'   => 'In spreadsheets and in the "Manage Items" area, display checkboxes, radio buttons and option values as they show in the upload form, instead of using the more compact defaults.' ),

        'gen_ssheet_on_close' => array( 'type'   => 'boolean',
                                        'params' => array(),
                                        'def'    => false,
                                        'desc'   => "When a webform is set to close automatically ( i.e. via the timer ), generate the spreadsheet in the correct ewz_image_uploads folder. This may be useful for those who download images via ftp, since the spreadsheet will then be in the same folder." ),
    // ************ NB: when adding new options, remember to add them to the validation class and to the delete list in uninstall.php

        'show_auto_close' => array( 'type'   => 'boolean',
                                    'params' => array(),
                                    'def'    => false,
                                     'desc'   => "When a webform is set to close automatically ( i.e. via the timer ), display the closing date-time in the webform." ),

        'will_close_txt' => array( 'type'   => 'string',
                                   'params' => array('maxlen' => 200, 'lines' => 1 ),
                                        'def'    => 'Upload will close at ',
                                        'desc'   => "When a webform is closed automatically ( i.e. via the timer ), display this text, followed by the closing date-time, in the webform." ),

        'show_auto_open' => array( 'type'   => 'boolean',
                                        'params' => array(),
                                        'def'    => false,
                                        'desc'   => "When a webform is set to open automatically ( i.e. via the timer ), display the opening date-time in the webform." ),
    // ************ NB: when adding new options, remember to add them to the validation class and to the delete list in uninstall.php

        'will_open_txt' => array( 'type'   => 'string',
                                  'params' => array('maxlen' => 200, 'lines' => 1 ),
                                  'def'    => 'Upload will open at ',
                                  'desc'   => "When a webform is opened automatically ( i.e. via the timer ), display this text, followed by the opening date-time, in the webform." ),

        'csv_ascii' => array( 'type'   => 'boolean',
                                        'params' => array(),
                                        'def'    => true,
                                        'desc'   => "When uploading .csv files, convert the data to ASCII format (i.e. remove accented characters). This setting should be left checked unless you have software capable of generating a correct .csv file in UTF8 format." ),

        'cs_warn' => array( 'type'   => 'boolean',
                            'params' => array(),
                                        'def'    => false,
                                        'desc'   => "Display a warning message if the EXIF data of a selected image does not have color space set to sRGB. ( Most, but not all image editing programs save the color space in the exif data. Checking this may occasionally generate warnings for perfectly valid sRGB images. ) " ),

 );
    // ************ NB: when adding new options, remember to add them to the validation class and to the delete list in uninstall.php


   /**
    * @var array<string, mixed> $options
    */
    protected $options;

    /**
     *
     * @return array<string, array{'type':string,'params':array<mixed>,'def':bool,'desc':string}>    $defaults
     */
    public function get_defaults(){
        return self::$defaults;
    }

    /**
     * @param  string $key
     * @return mixed  $options[$key]
     */
    public function get_setting($key){
        return $this->options[$key];
    }

    /**
     * @return array<string,string>
     */
    public static function get_img_size_names(){
        $sizes = array();
        foreach(get_intermediate_image_sizes() as $name ){
            if( get_option( "{$name}_size_w" ) && get_option( "{$name}_size_h" ) ){
                $sizes[$name] = $name;
            }
        }
        $sizes['full'] = 'full size';
        return $sizes;
    }

    /**
     * @return array<string>
     */
    public static function get_qual_opts(){
        return array_map('strval', array_keys(self::$qual_opts));
    }

    /**
     * @return array<string,string>
     */
    public static function get_jpeg_quality_opts(){
        return self::$qual_opts;
    }

    /**
     * @return array<string>
     */
    public static function get_margin_opts(){
        return self::$defaults['margin']['params']['opts'];
    }
    // NB: when adding new options, remember to add them to the delete list in uninstall.php

    /**
     * @param array<string,mixed> $init
     */
    public function __construct( $init = null )
    {
        // Allow Ewz-Rating to add more settings
        self::$defaults = apply_filters( 'ewz_settings_defaults', self::$defaults );

        if ( !$init  ) {
            $this->create_from_id( 0 );
        } elseif ( is_array( $init ) ) {
            $this->create_from_data( $init );
        }

        // can't use these expressions in the initial static declaration, so set them now
        // ( constructor is only used when setting )
        if( !isset( self::$defaults['attach_jpeg_qual']['params']['opts'] ) ){
            self::$defaults['attach_jpeg_qual']['params']['opts'] = self::$qual_opts;
        }
        if( !isset( self::$defaults['attach_img_size']['params']['opts'] ) ){
            self::$defaults['attach_img_size']['params']['opts'] = self::get_img_size_names();
        }
    }

    /**
     * @return void
     */
    protected function check_errors(){
        if( !is_array( $this->options ) ){
            throw new EWZ_Exception( 'Invalid options set' );
        }
        foreach( $this->options as $key => $val ){
            if( !isset( self::$defaults[$key] ) ){
                  throw new EWZ_Exception( "No default set for option $key" );
            }
        }
    }

    /**
     * @return int
     */
    public function save(){
        if( !current_user_can('manage_options') ){
            throw new EWZ_Exception( 'Insufficient permissions to edit EntryWizard settings' );
        }

        $this->check_errors();
        $saved = 0;
        foreach( $this->options as $key => $val ){
            if( self::$defaults[$key]['type'] == 'boolean' ){
                update_option( "ewz_$key", $val ? 1 : 0 );
                ++$saved;
            } elseif ( self::$defaults[$key]['type'] !== 'info' ){
                update_option( "ewz_$key", $val );
                ++$saved;
            }
        }
        return $saved;
    }

    /**
     * @return void
     */
    public function delete(){
        if( !current_user_can('manage_options') ){
            throw new EWZ_Exception( 'Insufficient permissions to edit EntryWizard settings' );
        }
       foreach( $this->options as $key => $val ){
            delete_option( "ewz_$key" );
        }
    }

    /**
     * @param string  $key
     *
     * @return mixed
     */

    public static function get_ewz_option( $key ){
        if( !isset(self::$defaults[$key]['def']) ){
            self::$defaults = apply_filters( 'ewz_settings_defaults', self::$defaults );
        }
        if( self::$defaults[$key]['type'] == 'boolean' ){
            return( (boolean) get_option( "ewz_$key", self::$defaults[$key]['def'] ) );
        } else {
            return get_option( "ewz_$key", self::$defaults[$key]['def'] );
        }
    }

    /**
     * @param int  $id
     * @return void
     */
    protected function create_from_id( $id ){
        foreach( self::$defaults as $key => $def_arr ){
            if( self::$defaults[$key]['type'] == 'boolean' ){
                $this->options[$key] = (boolean)get_option( "ewz_$key", $def_arr['def'] );

            } elseif ( self::$defaults[$key]['type'] == 'info' ) {
                $this->options[$key] = '';
            } else {
                $this->options[$key] = get_option( "ewz_$key", $def_arr['def'] );
            }
        }
    }

    /**
     * @param array<string,mixed>  $data
     * @return void
     */
    protected function create_from_data( $data ){

        $this->create_from_id(0);  // pick up Rating settings, and set all the defaults

        foreach( $data as $key => $val ){
            if( isset( self::$defaults[$key] ) ){
                $this->options[$key] = $data[$key];
            }
        }
    }
}