<?php
/**
 * Hooks for WikiEditor extension
 *
 * @file
 * @ingroup Extensions
 */

class WikiEditorHooks {

	/* Protected Static Members */

	protected static $features = array(

		/* Toolbar Features */

		'toolbar' => array(
			'preferences' => array(
				// Ideally this key would be 'wikieditor-toolbar'
				'usebetatoolbar' => array(
					'type' => 'toggle',
					'label-message' => 'wikieditor-toolbar-preference',
					'section' => 'editing/editor',
				),
			),
			'requirements' => array(
				'usebetatoolbar' => true,
			),
			'modules' => array(
				'ext.wikiEditor.toolbar',
			),
			'stylemodules' => array(
				'ext.wikiEditor.toolbar.styles',
			),
		),
		'dialogs' => array(
			'preferences' => array(
				// Ideally this key would be 'wikieditor-toolbar-dialogs'
				'usebetatoolbar-cgd' => array(
					'type' => 'toggle',
					'label-message' => 'wikieditor-toolbar-dialogs-preference',
					'section' => 'editing/editor',
				),
			),
			'requirements' => array(
				'usebetatoolbar-cgd' => true,
				'usebetatoolbar' => true,
			),
			'modules' => array(
				'ext.wikiEditor.dialogs',
			),
		),
		'hidesig' => array(
			'preferences' => array(
				'wikieditor-toolbar-hidesig' => array(
					'type' => 'toggle',
					'label-message' => 'wikieditor-toolbar-hidesig',
					'section' => 'editing/editor',
				),
			),
			'requirements' => array(
				'wikieditor-toolbar-hidesig' => true,
				'usebetatoolbar' => true,
			),
			'modules' => array(
				'ext.wikiEditor.toolbar.hideSig',
			),
		),

		/* Labs Features */

		'preview' => array(
			'preferences' => array(
				'wikieditor-preview' => array(
					'type' => 'toggle',
					'label-message' => 'wikieditor-preview-preference',
					'section' => 'editing/labs',
				),
			),
			'requirements' => array(
				'wikieditor-preview' => true,
			),
			'modules' => array(
				'ext.wikiEditor.preview',
			),
		),
		'previewDialog' => array(
			'preferences' => array(
				'wikieditor-previewDialog' => array(
					'type' => 'toggle',
					'label-message' => 'wikieditor-previewDialog-preference',
					'section' => 'editing/labs',
				),
			),
			'requirements' => array(
				'wikieditor-previewDialog' => true,
			),
			'modules' => array(
				'ext.wikiEditor.previewDialog',
			),
		),
		'publish' => array(
			'preferences' => array(
				'wikieditor-publish' => array(
					'type' => 'toggle',
					'label-message' => 'wikieditor-publish-preference',
					'section' => 'editing/labs',
				),
			),
			'requirements' => array(
				'wikieditor-publish' => true,
			),
			'modules' => array(
				'ext.wikiEditor.publish',
			),
		)
	);

	/* Static Methods */

	/**
	 * Checks if a certain option is enabled
	 *
	 * This method is public to allow other extensions that use WikiEditor to use the
	 * same configuration as WikiEditor itself
	 *
	 * @param $name string Name of the feature, should be a key of $features
	 * @return bool
	 */
	public static function isEnabled( $name ) {
		global $wgWikiEditorFeatures, $wgUser;

		// Features with global set to true are always enabled
		if ( !isset( $wgWikiEditorFeatures[$name] ) || $wgWikiEditorFeatures[$name]['global'] ) {
			return true;
		}
		// Features with user preference control can have any number of preferences to be specific values to be enabled
		if ( $wgWikiEditorFeatures[$name]['user'] ) {
			if ( isset( self::$features[$name]['requirements'] ) ) {
				foreach ( self::$features[$name]['requirements'] as $requirement => $value ) {
					// Important! We really do want fuzzy evaluation here
					if ( $wgUser->getOption( $requirement ) != $value ) {
						return false;
					}
				}
			}
			return true;
		}
		// Features controlled by $wgWikiEditorFeatures with both global and user set to false are awlways disabled
		return false;
	}

	/**
	 * EditPage::showEditForm:initial hook
	 *
	 * Adds the modules to the edit form
	 *
	 * @param $editPage EditPage the current EditPage object.
	 * @param $output OutputPage object.
	 * @return bool
	 */
	public static function editPageShowEditFormInitial( $editPage, $outputPage ) {
		if ( $editPage->contentModel !== CONTENT_MODEL_WIKITEXT ) {
			return true;
		}

		// Add modules for enabled features
		foreach ( self::$features as $name => $feature ) {
			if ( !self::isEnabled( $name ) ) {
				continue;
			}
			if ( isset( $feature['stylemodules'] ) ) {
				$outputPage->addModuleStyles( $feature['stylemodules'] );
			}
			if ( isset( $feature['modules'] ) ) {
				$outputPage->addModules( $feature['modules'] );
			}
		}
		return true;
	}

	/**
	 * EditPageBeforeEditToolbar hook
	 *
	 * Disable the old toolbar if the new one is enabled
	 *
	 * @param $toolbar html
	 * @return bool
	 */
	public static function EditPageBeforeEditToolbar( &$toolbar ) {
		if ( self::isEnabled( 'toolbar' ) ) {
			$toolbar = Html::rawElement(
				'div', array(
					'class' => 'wikiEditor-oldToolbar'
				),
				$toolbar
			);
		}
		return true;
	}

	/**
	 * GetPreferences hook
	 *
	 * Adds WikiEditor-releated items to the preferences
	 *
	 * @param $user User current user
	 * @param $defaultPreferences array list of default user preference controls
	 * @return bool
	 */
	public static function getPreferences( $user, &$defaultPreferences ) {
		global $wgWikiEditorFeatures;

		foreach ( self::$features as $name => $feature ) {
			if (
				isset( $feature['preferences'] ) &&
				( !isset( $wgWikiEditorFeatures[$name] ) || $wgWikiEditorFeatures[$name]['user'] )
			) {
				foreach ( $feature['preferences'] as $key => $options ) {
					$defaultPreferences[$key] = $options;
				}
			}
		}
		return true;
	}

	/**
	 * MakeGlobalVariablesScript hook
	 *
	 * Adds enabled/disabled switches for WikiEditor modules
	 * @param $vars array
	 * @return bool
	 */
	public static function resourceLoaderGetConfigVars( &$vars ) {
		global $wgWikiEditorFeatures;

		$configurations = array();
		foreach ( self::$features as $name => $feature ) {
			if (
				isset( $feature['configurations'] ) &&
				( !isset( $wgWikiEditorFeatures[$name] ) || self::isEnabled( $name ) )
			) {
				foreach ( $feature['configurations'] as $configuration ) {
					global $$configuration;
					$configurations[$configuration] = $$configuration;
				}
			}
		}
		if ( count( $configurations ) ) {
			$vars = array_merge( $vars, $configurations );
		}
		//expose magic words for use by the wikieditor toolbar
		WikiEditorHooks::getMagicWords( $vars );
		return true;
	}

	/**
	 * @param $vars array
	 * @return bool
	 */
	public static function makeGlobalVariablesScript( &$vars ) {
		// Build and export old-style wgWikiEditorEnabledModules object for back compat
		$enabledModules = array();
		foreach ( self::$features as $name => $feature ) {
			$enabledModules[$name] = self::isEnabled( $name );
		}

		$vars['wgWikiEditorEnabledModules'] = $enabledModules;
		return true;
	}

	/**
	 * Expose useful magic words which are used by the wikieditor toolbar
	 * @param $vars array
	 * @return bool
	 */
	private static function getMagicWords( &$vars ){
		$requiredMagicWords = array(
			'redirect',
			'img_right',
			'img_left',
			'img_none',
			'img_center',
			'img_thumbnail',
			'img_framed',
			'img_frameless',
		);
		foreach ( $requiredMagicWords as $name ) {
				$magicWords[$name] = MagicWord::get( $name )->getSynonym( 0 );
			}
		$vars['wgWikiEditorMagicWords'] = $magicWords;
	}

}