<?php


/* Basic plugin definitions */

define('GRAIN_VERSION', '0.0.7.1');

/* Make sure we don't expose any info if called directly */

if ( !function_exists( 'add_action' ) ) {
	echo "Hi there! Don't mind me.";
	exit;
}

/* If the user can't edit Grain Options, no use running this plugin */

add_action('init', 'grain_rolescheck' );

function grain_rolescheck () {
	if ( current_user_can( 'edit_theme_options' ) ) {
		// If the user can edit Grain Options, let the fun begin!
		add_action( 'admin_menu', 'grain_add_page');
		add_action( 'admin_init', 'grain_init' );
		add_action( 'admin_init', 'grain_mlu_init' );
	}
}

/* Loads the file for option sanitization */

add_action('init', 'grain_load_sanitization' );

function grain_load_sanitization() {
	require_once dirname( __FILE__ ) . '/grain-options-sanitize.php';
}

/* 
 * Creates the settings in the database by looping through the array
 * we supplied in options.php.  This is a neat way to do it since
 * we won't have to save settings for headers, descriptions, or arguments.
 *
 * Read more about the Settings API in the WordPress codex:
 * http://codex.wordpress.org/Settings_API
 *
 */

function grain_init() {

	// Include the required files
	require_once dirname( __FILE__ ) . '/grain-options-interface.php';
	require_once dirname( __FILE__ ) . '/grain-options-medialibrary-uploader.php';
	
	// Loads the options array from the theme
	if ( $grain_optionsfile = locate_template( array('options.php') ) ) {
		get_template_part('options');
	}
	else if (file_exists( dirname( __FILE__ ) . '/options.php' ) ) {
		require_once dirname( __FILE__ ) . '/options.php';
	}
	
	$grain_settings = get_option('grain' );
	
	// Updates the unique option id in the database if it has changed
	grain_option_name();
	
	// Gets the unique id, returning a default if it isn't defined
	if ( isset($grain_settings['id']) ) {
		$grain_option_name = $grain_settings['id'];
	}
	else {
		$grain_option_name = 'grain';
	}
	
	// If the option has no saved data, load the defaults
	if ( ! get_option($grain_option_name) ) {
		grain_setdefaults();
	}
	
	// Registers the settings fields and callback
	register_setting( 'grain', $grain_option_name, 'grain_validate' );
}

/* 
 * Adds default options to the database if they aren't already present.
 * May update this later to load only on plugin activation, or theme
 * activation since most people won't be editing the options.php
 * on a regular basis.
 *
 * http://codex.wordpress.org/Function_Reference/add_option
 *
 */

function grain_setdefaults() {
	
	$grain_settings = get_option('grain');

	// Gets the unique option id
	$grain_option_name = $grain_settings['id'];
	
	/* 
	 * Each theme will hopefully have a unique id, and all of its options saved
	 * as a separate option set.  We need to track all of these option sets so
	 * it can be easily deleted if someone wishes to remove the plugin and
	 * its associated data.  No need to clutter the database.  
	 *
	 */
	
	if ( isset($grain_settings['knownoptions']) ) {
		$grain_knownoptions =  $grain_settings['knownoptions'];
		if ( !in_array($grain_option_name, $grain_knownoptions) ) {
			array_push( $grain_knownoptions, $grain_option_name );
			$grain_settings['knownoptions'] = $grain_knownoptions;
			update_option('grain', $grain_settings);
		}
	} else {
		$grain_newoptionname = array($grain_option_name);
		$grain_settings['knownoptions'] = $grain_newoptionname;
		update_option('grain', $grain_settings);
	}
	
	// Gets the default options data from the array in options.php
	$grain_options = grain_options();
	
	// If the options haven't been added to the database yet, they are added now
	$grain_values = of_get_default_values();
	
	if ( isset($grain_values) ) {
		add_option( $grain_option_name, $grain_values ); // Add option with default settings
	}
}

/* Add a subpage called "Grain Options" to the appearance menu. */

if ( !function_exists( 'grain_add_page' ) ) {
function grain_add_page() {

	$grain_of_page = add_theme_page('Grain Options', 'Grain Options', 'edit_theme_options', 'options-framework','grain_page');
	
	// Adds actions to hook in the required css and javascript
	add_action("admin_print_styles-$grain_of_page",'grain_load_styles');
	add_action("admin_print_scripts-$grain_of_page", 'grain_load_scripts');
	
}
}

/* Loads the CSS */

function grain_load_styles() {
	wp_enqueue_style('admin-style', GRAIN_DIRECTORY.'css/grain-options-style.css');
}	

/* Loads the javascript */

function grain_load_scripts() {
	wp_enqueue_script('options-custom', GRAIN_DIRECTORY.'js/grain-options-custom.js', array('jquery'));
}


/* 
 * Builds out the options panel.
 *
 * If we were using the Settings API as it was likely intended we would use
 * do_settings_sections here.  But as we don't want the settings wrapped in a table,
 * we'll call our own custom grain_fields.  See options-interface.php
 * for specifics on how each individual field is generated.
 *
 * Nonces are provided using the settings_fields()
 *
 */

if ( !function_exists( 'grain_page' ) ) {
function grain_page() {
	$grain_return = grain_fields();
	settings_errors();
	?>
    
	<div class="wrap">
    <?php screen_icon( 'themes' ); ?>
    <h2 class="nav-tab-wrapper">
        <?php echo $grain_return[1]; ?>
    </h2>
    
    <div class="metabox-holder">
    <div id="grain" class="postbox">
		<form action="options.php" method="post">
		<?php settings_fields('grain'); ?>

		<?php echo $grain_return[0]; /* Settings */ ?>
        
        <div id="grain-submit">
			<input type="submit" class="button-primary" name="update" value="<?php esc_attr_e( 'Save Options', 'grain' ); ?>" />
            <input type="submit" class="reset-button button-secondary" name="reset" value="<?php esc_attr_e( 'Restore Defaults', 'grain' ); ?>" onclick="return confirm( '<?php print esc_js( __( 'Click OK to reset. Any theme settings will be lost!', 'grain' ) ); ?>' );" />
            <div class="clear"></div>
		</div>
	</form>
</div> <!-- / #container -->
</div>
</div> <!-- / .wrap -->

<?php
}
}

/** 
 * Validate Options.
 *
 * This runs after the submit/reset button has been clicked and
 * validates the inputs.
 *
 * @uses $_POST['reset']
 * @uses $_POST['update']
 */
function grain_validate( $grain_input ) {

	/*
	 * Restore Defaults.
	 *
	 * In the event that the user clicked the "Restore Defaults"
	 * button, the options defined in the theme's options.php
	 * file will be added to the option for the active theme.
	 */
	 
	if ( isset( $_POST['reset'] ) ) {
		add_settings_error( 'options-framework', 'restore_defaults', __( 'Default options restored.', 'grain' ), 'updated fade' );
		return of_get_default_values();
	}

	/*
	 * Udpdate Settings.
	 */
	 
	if ( isset( $_POST['update'] ) ) {
		$grain_clean = array();
		$grain_options = grain_options();
		foreach ( $grain_options as $grain_option ) {

			if ( ! isset( $grain_option['id'] ) ) {
				continue;
			}

			if ( ! isset( $grain_option['type'] ) ) {
				continue;
			}

			$grain_id = preg_replace( '/\W/', '', strtolower( $grain_option['id'] ) );

			// For a value to be submitted to database it must pass through a sanitization filter
			if ( has_filter( 'of_sanitize_' . $grain_option['type'] ) ) {
				$grain_clean[$grain_id] = apply_filters( 'of_sanitize_' . $grain_option['type'], $grain_input[$grain_id], $grain_option );
			}
		}

		add_settings_error( 'options-framework', 'save_options', __( 'Options saved.', 'grain' ), 'updated fade' );
		return $grain_clean;
	}

	/*
	 * Request Not Recognized.
	 */
	
	return of_get_default_values();
}

/**
 * Format Configuration Array.
 *
 * Get an array of all default values as set in
 * options.php. The 'id','std' and 'type' keys need
 * to be defined in the configuration array. In the
 * event that these keys are not present the option
 * will not be included in this function's output.
 *
 * @return    array     Rey-keyed options configuration array.
 *
 * @access    private
 */
 
function of_get_default_values() {
	$grain_output = array();
	$grain_config = grain_options();
	foreach ( (array) $grain_config as $grain_option ) {
		if ( ! isset( $grain_option['id'] ) ) {
			continue;
		}
		if ( ! isset( $grain_option['std'] ) ) {
			continue;
		}
		if ( ! isset( $grain_option['type'] ) ) {
			continue;
		}
		if ( has_filter( 'of_sanitize_' . $grain_option['type'] ) ) {
			$grain_output[$grain_option['id']] = apply_filters( 'of_sanitize_' . $grain_option['type'], $grain_option['std'], $grain_option );
		}
	}
	return $grain_output;
}

/**
 * Add Grain Options menu item to Admin Bar.
 */
 
add_action( 'wp_before_admin_bar_render', 'grain_adminbar' );

function grain_adminbar() {
	
	global $wp_admin_bar;
	
	$wp_admin_bar->add_menu( array(
		'parent' => 'appearance',
		'id' => 'of_theme_options',
		'title' => __( 'Grain Options', 'grain' ),
		'href' => admin_url( 'themes.php?page=options-framework' )
  ));
}

if ( ! function_exists( 'grain_get_option' ) ) {

	/**
	 * Get Option.
	 *
	 * Helper function to return the theme option value.
	 * If no value has been saved, it returns $grain_default.
	 * Needed because options are saved as serialized strings.
	 */
	 
	function grain_get_option( $grain_name, $grain_default = false ) {
		$grain_config = get_option( 'grain' );

		if ( ! isset( $grain_config['id'] ) ) {
			return $grain_default;
		}

		$grain_options = get_option( $grain_config['id'] );

		if ( isset( $grain_options[$grain_name] ) ) {
			return $grain_options[$grain_name];
		}

		return $grain_default;
	}
}