<?php
/**
 * Widget CSS Classes Plugin Settings
 *
 * Settings
 * @author Jory Hogeveen <info@keraweb.nl>
 * @author C.M. Kendrick <cindy@cleverness.org>
 * @package widget-css-classes
 * @version 1.5.3
 */

/**
 * Settings class, based on class from Theme.fm (see link)
 * @package widget-css-classes
 * @subpackage includes
 * @link http://theme.fm/2011/10/how-to-create-tabs-with-the-settings-api-in-wordpress-2590/
 */
class WCSSC_Settings {

	/**
	 * @var string
	 */
	protected $general_key = '';

	/**
	 * @var string
	 */
	protected $plugin_key = 'widget-css-classes-settings';

	/**
	 * @var array
	 */
	protected $plugin_tabs = array();

	/**
	 * @var array
	 */
	protected $general_settings = array();

	/**
	 * @var string
	 */
	protected $current_tab = '';

	public function __construct() {
		add_action( 'admin_init', array( $this, 'load_settings' ) );
		add_action( 'admin_init', array( $this, 'register_general_settings' ) );
		add_action( 'admin_init', array( $this, 'register_importexport_settings' ) );
		add_action( 'admin_menu', array( $this, 'add_admin_menus' ) );
	}

	public function load_settings() {
		$this->general_settings = WCSSC_Lib::get_settings();
		$this->general_key      = WCSSC_Lib::$settings_key;
	}

	public function section_general_desc() {
	}

	public function register_general_settings() {
		$this->plugin_tabs[ $this->general_key ] = esc_attr__( 'Widget CSS Classes Settings', WCSSC_Lib::DOMAIN );
		// @codingStandardsIgnoreLine >> yeah yeah, I know...
		$this->current_tab = isset( $_GET['tab'] ) ? $_GET['tab'] : $this->general_key;

		register_setting( $this->general_key, $this->general_key, array( $this, 'validate_input' ) );
		add_settings_section( 'section_general', esc_attr__( 'Widget CSS Classes Settings', WCSSC_Lib::DOMAIN ), array( $this, 'section_general_desc' ), $this->general_key );
		add_settings_field(
			'show_number',
			esc_attr__( 'Add Widget Number Classes', WCSSC_Lib::DOMAIN ),
			array( $this, 'show_yes_no_option' ),
			$this->general_key,
			'section_general',
			array(
				'key' => 'show_number',
			)
		);
		add_settings_field(
			'show_location',
			esc_attr__( 'Add First/Last Classes', WCSSC_Lib::DOMAIN ),
			array( $this, 'show_yes_no_option' ),
			$this->general_key,
			'section_general',
			array(
				'key' => 'show_location',
			)
		);
		add_settings_field(
			'show_evenodd',
			esc_attr__( 'Add Even/Odd Classes', WCSSC_Lib::DOMAIN ),
			array( $this, 'show_yes_no_option' ),
			$this->general_key,
			'section_general',
			array(
				'key' => 'show_evenodd',
			)
		);
		add_settings_field(
			'show_id',
			esc_attr__( 'Show Additional Field for ID', WCSSC_Lib::DOMAIN ),
			array( $this, 'show_yes_no_option' ),
			$this->general_key,
			'section_general',
			array(
				'key' => 'show_id',
			)
		);
		add_settings_field(
			'type',
			esc_attr__( 'Class Field Type', WCSSC_Lib::DOMAIN ),
			array( $this, 'type_option' ),
			$this->general_key,
			'section_general'
		);
		add_settings_field(
			'defined_classes',
			esc_attr__( 'Predefined Classes', WCSSC_Lib::DOMAIN ),
			array( $this, 'defined_classes_option' ),
			$this->general_key,
			'section_general'
		);
		add_settings_field(
			'fix_widget_params',
			esc_attr__( 'Fix widget parameters', WCSSC_Lib::DOMAIN ),
			array( $this, 'show_yes_no_option' ),
			$this->general_key,
			'section_general',
			array(
				'key'  => 'fix_widget_params',
				'desc' => esc_html__( 'Wrap widget in a <div> element if the parameters are invalid.', WCSSC_Lib::DOMAIN ),
			)
		);
		add_settings_field(
			'filter_unique',
			esc_attr__( 'Remove duplicate classes', WCSSC_Lib::DOMAIN ),
			array( $this, 'show_yes_no_option' ),
			$this->general_key,
			'section_general',
			array(
				'key'  => 'filter_unique',
				'desc' => esc_html__( 'Plugins that run after this plugin could still add duplicates.', WCSSC_Lib::DOMAIN ),
			)
		);
		add_settings_field(
			'translate_classes',
			esc_attr__( 'Translate classes', WCSSC_Lib::DOMAIN ),
			array( $this, 'show_yes_no_option' ),
			$this->general_key,
			'section_general',
			array(
				'key'  => 'translate_classes',
				'desc' => esc_html__( 'Translate classes like `widget-first` and `widget-even`.', WCSSC_Lib::DOMAIN )
					// Translators: %s stands for a link to translate.wordpress.org.
					. ' ' . sprintf( esc_html__( 'Translations are taken from %s', WCSSC_Lib::DOMAIN ), '<a href="https://translate.wordpress.org/projects/wp-plugins/widget-css-classes" target="_blank">translate.wordpress.org</a>' ),
			)
		);
		do_action( 'widget_css_classes_settings' );
	}

	public function show_yes_no_option( $args ) {
		if ( ! $args['key'] ) return;
		$key = esc_attr( $args['key'] );
		?>
		<label><input type="radio" name="<?php echo esc_attr( $this->general_key . '[' . $key . ']' ); ?>" value="1" <?php checked( $this->general_settings[ $key ], true ); ?> /> <?php esc_attr_e( 'Yes', WCSSC_Lib::DOMAIN ); ?></label> &nbsp;
		<label><input type="radio" name="<?php echo esc_attr( $this->general_key . '[' . $key . ']' ); ?>" value="0" <?php checked( $this->general_settings[ $key ], false ); ?> /> <?php esc_attr_e( 'No', WCSSC_Lib::DOMAIN ); ?></label>
		<?php
		if ( ! empty( $args['desc'] ) ) {
			echo WCSSC::do_description( $args['desc'] ); // @codingStandardsIgnoreLine >> no valid esc function.
		}
	}

	public function type_option() {
		?>
		<label><input type="radio" class="wcssc_type" name="<?php echo esc_attr( $this->general_key ) . '[type]'; ?>" value="1" <?php checked( $this->general_settings['type'], 1 ); ?> /> <?php esc_attr_e( 'Text', WCSSC_Lib::DOMAIN ); ?></label> &nbsp;
		<label><input type="radio" class="wcssc_type" name="<?php echo esc_attr( $this->general_key ) . '[type]'; ?>" value="2" <?php checked( $this->general_settings['type'], 2 ); ?> /> <?php esc_attr_e( 'Predefined', WCSSC_Lib::DOMAIN ); ?></label> &nbsp;
		<label><input type="radio" class="wcssc_type" name="<?php echo esc_attr( $this->general_key ) . '[type]'; ?>" value="3" <?php checked( $this->general_settings['type'], 3 ); ?> /> <?php esc_attr_e( 'Both', WCSSC_Lib::DOMAIN ); ?></label> &nbsp;
		<label><input type="radio" class="wcssc_type" name="<?php echo esc_attr( $this->general_key ) . '[type]'; ?>" value="0" <?php checked( $this->general_settings['type'], 0 ); ?> /> <?php esc_attr_e( 'None', WCSSC_Lib::DOMAIN ); ?></label>
		<?php
	}

	public function defined_classes_option() {
		wp_enqueue_script( 'jquery-ui-sortable' );
		$presets = $this->general_settings['defined_classes'];
		?>
		<div class="wcssc_sortable">
		<?php
		if ( count( $presets ) > 1 ) {
			foreach ( $presets as $key => $preset ) {
			?>
				<p class="wcssc_defined_classes">
					<a class="wcssc_sort" href="#"><span class="dashicons dashicons-sort"></span></a>
					<input type="text" name="<?php echo esc_attr( $this->general_key ) . '[defined_classes][' . esc_attr( $key ) . ']'; ?>" value="<?php echo esc_attr( $preset ); ?>" />
					<a class="wcssc_remove" href="#"><span class="dashicons dashicons-dismiss"></span></a>
				</p>
			<?php
			}
			?>
			<p class="wcssc_defined_classes wcssc_sort_fixed">
				<a class="wcssc_sort" href="#"><span class="dashicons dashicons-sort"></span></a>
				<input type="text" name="<?php echo esc_attr( $this->general_key ) . '[defined_classes][]'; ?>" value="" />
				<a href="#" class="wcssc_copy" rel=".wcssc_defined_classes"><span class="dashicons dashicons-plus-alt"></span></a>
				<a class="wcssc_remove" href="#"><span class="dashicons dashicons-dismiss"></span></a>
			</p>
		<?php
		} else {
			$value = ( ! empty( $this->general_settings['defined_classes'][0] ) ) ? $this->general_settings['defined_classes'][0] : '';
			?>
			<p class="wcssc_defined_classes wcssc_sort_fixed">
				<a class="wcssc_sort" href="#"><span class="dashicons dashicons-sort"></span></a>
				<input type="text" name="<?php echo esc_attr( $this->general_key ) . '[defined_classes][]'; ?>" value="<?php echo esc_attr( $value ); ?>" />
				<a href="#" class="wcssc_copy" rel=".wcssc_defined_classes"><span class="dashicons dashicons-plus-alt"></span></a>
				<a class="wcssc_remove" href="#"><span class="dashicons dashicons-dismiss"></span></a>
			</p>
		<?php
		}
		?>
		</div>
		<?php
	}

	/**
	 * @todo Move to separate class or split in different methods.
	 * @SuppressWarnings(PHPMD.CyclomaticComplexity)
	 * @SuppressWarnings(PHPMD.NPathComplexity)
	 */
	public function register_importexport_settings() {

		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		// @codingStandardsIgnoreLine
		$get = $_GET; $post = $_POST;

		$this->plugin_tabs['importexport'] = esc_attr__( 'Import/Export', WCSSC_Lib::DOMAIN );

		$wcssc_message_class = '';
		$wcssc_message       = '';
		if ( isset( $get['wcssc_message'] ) ) {
			switch ( $get['wcssc_message'] ) {
				case 1:
					$wcssc_message_class = 'updated';
					$wcssc_message       = esc_attr__( 'Settings Imported', WCSSC_Lib::DOMAIN );
					break;
				case 2:
					$wcssc_message_class = 'error';
					$wcssc_message       = esc_attr__( 'Invalid Settings File', WCSSC_Lib::DOMAIN );
					break;
				case 3:
					$wcssc_message_class = 'error';
					$wcssc_message       = esc_attr__( 'No Settings File Selected', WCSSC_Lib::DOMAIN );
					break;
			}
		}

		if ( ! empty( $wcssc_message ) ) {
			echo '<div class=" ' . esc_attr( $wcssc_message_class ) . ' "><p>' . esc_html( $wcssc_message ) . '</p></div>';
		}

		// export settings
		if ( isset( $get['widget-css-classes-settings-export'] ) ) {
			header( 'Content-Disposition: attachment; filename=widget-css-classes-settings.txt' );
			header( 'Content-Type: text/plain; charset=utf-8' );
			$general = get_option( 'WCSSC_options' );

			echo "[START=WCSSC SETTINGS]\n";
			foreach ( $general as $id => $text ) {
				// @codingStandardsIgnoreLine >> wp_json_encode is WP 4.1+
				echo "$id\t" . json_encode( $text ) . "\n";
			}
			echo '[STOP=WCSSC SETTINGS]';
			exit;
		}

		// import settings
		if ( isset( $post['widget-css-classes-settings-import'] ) ) {
			$wcssc_message = 3;
			if ( $_FILES['widget-css-classes-settings-import-file']['tmp_name'] ) {
				$wcssc_message = 2;
				$import        = explode(
					"\n",
					// @codingStandardsIgnoreLine >> yeah yeah, I know...
					file_get_contents( $_FILES['widget-css-classes-settings-import-file']['tmp_name'] )
				);
				if ( array_shift( $import ) === '[START=WCSSC SETTINGS]' && array_pop( $import ) === '[STOP=WCSSC SETTINGS]' ) {
					$options = WCSSC_Lib::get_settings();
					foreach ( $import as $import_option ) {
						list( $key, $value ) = explode( "\t", $import_option );

						$options[ $key ] = json_decode( sanitize_text_field( $value ) );
						if ( $options['dropdown'] ) { // Update for 1.3.0
							$options['defined_classes'] = $options['dropdown'];
							unset( $options['dropdown'] );
						}
					}
					WCSSC_Lib::update_settings( $options );
					$wcssc_message = 1;
				}
			}

			wp_safe_redirect( admin_url( '/options-general.php?page=widget-css-classes-settings&tab=importexport&wcssc_message=' . esc_attr( $wcssc_message ) ) );
			exit;
		}
	}

	/**
	 * @param  array $input
	 * @return array
	 */
	public function validate_input( $input ) {
		WCSSC_Lib::set_settings( $input );
		return WCSSC_Lib::get_settings();
	}

	public function add_admin_menus() {
		add_options_page( esc_attr__( 'Widget CSS Classes', WCSSC_Lib::DOMAIN ), esc_attr__( 'Widget CSS Classes', WCSSC_Lib::DOMAIN ), 'manage_options', 'widget-css-classes-settings', array( $this, 'plugin_options_page' ) );
	}

	/*
	 * Plugin Options page rendering goes here, checks
	 * for active tab and replaces key with the related
	 * settings key. Uses the plugin_options_tabs method
	 * to render the tabs.
	 */
	public function plugin_options_page() {
		$tab = $this->current_tab;
		?>
	<div class="wrap">
		<?php $this->plugin_options_tabs(); ?>
		<form method="post" action="options.php" enctype="multipart/form-data">
			<?php settings_fields( $tab ); ?>
			<?php do_settings_sections( $tab ); ?>
			<?php if ( 'importexport' === $tab ) $this->importexport_fields(); ?>
			<?php if ( 'importexport' !== $tab ) submit_button(); ?>
		</form>
	</div>
	<?php
		add_action( 'in_admin_footer', array( 'WCSSC_Lib', 'admin_footer' ) );
	}

	/*
	 * Renders our tabs in the plugin options page,
	 * walks through the object's tabs array and prints
	 * them one by one. Provides the heading for the
	 * plugin_options_page method.
	 */
	public function plugin_options_tabs() {

		echo '<h1 class="nav-tab-wrapper">';
		foreach ( $this->plugin_tabs as $tab_key => $tab_caption ) {
			$active = $this->current_tab === $tab_key ? 'nav-tab-active' : '';
			echo '<a class="nav-tab ' . esc_attr( $active ) . '" href="?page=' . esc_attr( $this->plugin_key ) . '&amp;tab=' . esc_attr( $tab_key ) . '">' . esc_html( $tab_caption ) . '</a>';
		}
		echo '</h1>';
	}

	public function importexport_fields() {
	?>
		<h3><?php esc_html_e( 'Import/Export Settings', WCSSC_Lib::DOMAIN ); ?></h3>

		<p><a class="submit button" href="?widget-css-classes-settings-export"><?php esc_attr_e( 'Export Settings', WCSSC_Lib::DOMAIN ); ?></a></p>

		<p>
			<input type="hidden" name="widget-css-classes-settings-import" id="widget-css-classes-settings-import" value="true" />
			<?php submit_button( esc_attr__( 'Import Settings', WCSSC_Lib::DOMAIN ), 'button', 'widget-css-classes-settings-submit', false ); ?>
			<input type="file" name="widget-css-classes-settings-import-file" id="widget-css-classes-settings-import-file" />
		</p>
	<?php
	}
}
