<?php

/**
 * This file contains the osMulti class which initializes the plugin and provides global variables/methods for use in the rest of the plugin.
 *
 * @package PublishPress Series Multi
 * @since 0.1
 */

if (!class_exists('osMulti')) {

	class osMulti
	{

		var $settings;
		var $version = OS_MULTI_VER;
		var $os_multi_domain = 'publishpress-series-pro';
		var $message_id = 1;

		//__constructor
		function __construct()
		{


			//initial setup stuff
			add_action('publishpress_series_pro_after_init', array(&$this, 'add_settings'));
			add_action('admin_enqueue_scripts', array(&$this, 'register_scripts_styles'));
			add_action('admin_init', array($this, 'load_custom_columns'));

			//replacing PublishPress Series hooks/filters
			add_action('quick_edit_custom_box', array(&$this, 'inline_edit'), 9, 2);
			add_action('admin_print_scripts-edit.php', array(&$this, 'inline_edit_js'));
			add_action('admin_print_scripts-post.php', array(&$this, 'add_series_js'));
			add_action('admin_print_scripts-post-new.php', array(&$this, 'add_series_js'));
			add_action('admin_print_styles-edit.php', array(&$this, 'inline_edit_css'));
			add_action('wp_ajax_add_series', array(&$this, 'ajax_series'));
			add_action('add_meta_boxes', array($this, 'meta_box'));

		}

		function load_custom_columns()
		{
			$posttypes = apply_filters('orgseries_posttype_support', array('post'));
			foreach ($posttypes as $posttype) {
				$filter_ref = ($posttype == 'post') ? 'manage_posts_custom_column' : 'manage_' . $posttype . 'posts_custom_column';
				$filter_ref = ($posttype == 'page') ? 'manage_pages_custom_column' : $filter_ref;
				add_action($filter_ref, array($this, 'posts_custom_column_action'), 12, 2);
			}
		}

		function register_scripts_styles()
		{
			global $orgseries;

			$org_opt = (is_object($orgseries) && isset($orgseries->settings)) ? $orgseries->settings : [];

			$metabox_show_add_new = isset($org_opt['metabox_show_add_new']) ? (int) $org_opt['metabox_show_add_new'] : 0;

			$url = OS_MULTI_URL . 'js/';
			$c_url = OS_MULTI_URL . 'css/';
			wp_register_script('inline-edit-series-multiples', $url . 'inline-edit-series-multiples.js');
			wp_register_script('series-multiples-add', $url . 'series-multiples.js', array('jquery', 'jquery-ui-core', 'jquery-color'));
			wp_localize_script(
				'series-multiples-add',
				'seriesL10n',
				array(
					'add' => esc_attr(__('Add New', 'publishpress-series-pro')),
					'metabox_show_add_new' => $metabox_show_add_new,
					'how' => __('To remove a post from series, just deselect any checkboxes', 'publishpress-series-pro'),
					'addnonce' => wp_create_nonce('add-series-nonce')
				)
			);
			wp_enqueue_style('series-multiples-inline-edit', $c_url . 'series-multiples-edit-php.css');
		}

		function add_settings()
		{
			//we'll use this for setting up the defaults for the os_multi options.  However there are none yet so let's get out of here.
			return;
		}

		function inline_edit($column_name, $type)
		{
			//'publishpress-series-pro'
			$posttypes = apply_filters('orgseries_posttype_support', array('post'));
			if (in_array($type, $posttypes) && $column_name == ppseries_get_series_slug()) {
				?>
					<fieldset class="inline-edit-col-right">
						<div class="inline-edit-col">
							<div class="inline_edit_series_">
								<span class="title inline-edit-categories-label"><?php _e('Series:', 'publishpress-series-pro'); ?></span>
								<ul id="series-checklist-ul" class="cat-checklist series-checklist">
									<?php $this->wp_series_checklist(null, 'name=post_series&class=post_series_select&id=series_part_'); ?>
								</ul>
								<input type="hidden" name="series_post_id" class="series_post_id"/>
								<input type="hidden" name="is_series_save" value="1"/>


							</div>
						</div>
					</fieldset>
				<?php
			}
		}

		function inline_edit_js()
		{
			wp_enqueue_script('inline-edit-series-multiples');
		}

		function add_series_js()
		{
			if (current_user_can('manage_publishpress_series')) {
				wp_enqueue_script('series-multiples-add');
			}
		}

		function inline_edit_css()
		{
			wp_enqueue_style('series-multiples-inline-edit');
		}

		function wp_series_checklist($post_id = 0, $args = array())
		{
			global $orgseries;

			if (is_object($orgseries) && isset($orgseries->settings)) {
				$org_opt = $orgseries->settings;
			} else {
				$org_opt = [];
			}
		
			$metabox_series_order = is_array($org_opt) && isset($org_opt['metabox_series_order']) ? $org_opt['metabox_series_order'] : 'default';

			$sp = array();
			$defaults = array(
				'selected_series' => false,
				'popular_series' => false,
				'walker' => null,
				'taxonomy' => ppseries_get_series_slug(),
				'checked_ontop' => true,
				'name' => 'post_series',
				'id' => '',
				'class' => 'postform'
			);

			$args = wp_parse_args($args, $defaults);
			extract($args, EXTR_SKIP);

			$post_id = (int) $post_id;

			if (empty($walker) || !is_a($walker, 'Walker'))
				$walker = new Walker_SeriesChecklist;

			$tax = get_taxonomy($taxonomy);
			$args['disabled'] = !current_user_can($tax->cap->assign_terms);


			$args['selected_series'] = (array) $selected_series;


			if ($post_id) {
				$args['selected_series'] = wp_get_object_terms($post_id, $taxonomy, array('fields' => 'ids'));
			} else {
				$args['selected_series'] = array();
			}


			if (is_array($popular_series))
				$args['popular_series'] = $popular_series;
			else
				$args['popular_series'] = get_terms($taxonomy, array('fields' => 'ids', 'orderby' => 'count', 'order' => 'DESC', 'number' => 10, 'hierarchical' => false));

			$term_options = array('get' => 'all', 'orderby' => 'term_order');

			$series = (array) get_terms($taxonomy, $term_options);

			if ($metabox_series_order === 'a-z') {
				uasort($series, function($a, $b) {
					return strcasecmp($a->name, $b->name);
				});
			} elseif ($metabox_series_order === 'z-a') {
				uasort($series, function($a, $b) {
					return strcasecmp($b->name, $a->name);
				});
			}

			//need to send an array of series_parts to the assembler as well.
			if (!empty($post_id)) {
				foreach ($series as $ser) {
					$series_part = wp_series_part($post_id, $ser->term_id);
					$sp[$ser->term_id] = $series_part;
				}
			} else {
				$sp = array();
			}

			$args['series_parts'] = $sp;

			if ($checked_ontop) {
				//Post process $series rather than adding an exclude to the get_terms() query to keep the query the same across all posts (for any query cache)
				$checked_series = array();
				$keys = array_keys($series);
				foreach ($keys as $k) {
					if (in_array($series[$k]->term_id, $args['selected_series'])) {
						$checked_series[] = $series[$k];
						unset($series[$k]);
					}
				}

				// Put checked series on top
				echo call_user_func_array(array(&$walker, 'walk'), array($checked_series, 0, $args));
			}

			//Then the rest of them
			echo call_user_func_array(array(&$walker, 'walk'), array($series, 0, $args));
		}

		function ajax_series()
		{
			$response = array();

			if (!current_user_can('manage_publishpress_series'))
				$response['error'] = __('Sorry but you don\'t have permission to add series', 'publishpress-series-pro');

			if (!check_ajax_referer('add-series-nonce', 'addnonce', false)) {
				$response['error'] = 'Sorry but security check failed';
			}
			$new_nonce = wp_create_nonce('add-series-nonce');

			$name = sanitize_text_field($_POST['newseries']);

			$series_name = trim($name);
			if (!$series_nicename = sanitize_title($series_name))
				$response['error'] = __('The name you picked isn\'t sanitizing correctly. Try something different.', 'publishpress-series-pro');
			if (!$series_id = series_exists($series_name)) {
				$ser_id = wp_create_single_series($series_name);
				$series_id = $ser_id['term_id'];
			} else {
				$response['error'] = __('Hmm... it looks like there is already a series with that name. Try something else', 'publishpress-series-pro');
			}

			$series_name = esc_html(stripslashes($series_name));

			if (!isset($response['error'])) {
				$response = array(
					'id' => $series_id,
					'html' => "\n<li id='series-{$series_id}' class='series-added-indicator'>" . "<div class='series-li-part'><div><label for='in-series-{$series_id}' class='selectit'>" . '<input value="' . $series_id . '" type="checkbox" name="post_series[]" id="in-series-' . $series_id . '" checked /><input type="hidden" name="is_series_save" value="1" /><span class="li-series-name">' . $series_name . '</span></label></div><div style="display: none;">' . '<span class="to_series_part"><input id="series-part-' . $series_id . '" type="text" class="series_part" size="3" value="" name="series_part[' . $series_id . ']" /></span></div></div></li>',
					'new_nonce' => $new_nonce,
					'error' => false
				);
			}
			echo json_encode($response);
			exit();
		}

		function meta_box()
		{
			$posttypes = apply_filters('orgseries_posttype_support', array('post'));
			foreach ($posttypes as $posttype) {
				remove_meta_box('seriesdiv', $posttype, 'side'); //remove default meta box included with PublishPress Series Core plugin
				add_meta_box(
					'newseriesdiv',
					__('Series', 'publishpress-series-pro'),
					array($this, 'add_meta_box'),
					$posttype,
					'side'
				);
			}
		}

		function add_meta_box()
		{
			global $post, $postdata, $content, $orgseries;
			$id = isset($post) ? $post->ID : $postdata->ID;
			$ser_id = wp_get_post_series($id);
			$ser_id = is_array($ser_id) && isset($ser_id[0]) ? $ser_id[0] : '';
			$org_opt = $orgseries->settings;


			$metabox_show_post_title_in_widget = isset($org_opt['metabox_show_post_title_in_widget']) ? (int) $org_opt['metabox_show_post_title_in_widget'] : 0;

			if (current_user_can('manage_publishpress_series')) {
				?>
					<div class="series-metadiv">
						<div class="tabs-panel">
							<p id="jaxseries"></p>
					<?php } ?>
					<span id="series-ajax-response"></span>

					<div class="ppseries-title-container" style="display: none;">
						<span class="series-title"><?php _e('Series', 'publishpress-series-pro'); ?></span>
						<span class="series-part" style="display: none;"><?php _e('Part', 'publishpress-series-pro'); ?></span>
					</div>
					<div class="clear"></div>
					<ul id="serieschecklist" class="list:series serieschecklist categorychecklist form-no-clear">
						<?php $this->wp_series_checklist($post->ID); ?>
					</ul>

					<div class="series-part-wrap"></div>
					<div class="series-metabox-post-title-in-widget" style="<?php echo ($metabox_show_post_title_in_widget === 0) ? 'display: none;' : ''; ?>">
						<strong>
							<?php _e('Post title in widget:', 'publishpress-series-pro'); ?></strong>
						<p id="part-description" class="howto">
							<?php _e('A short title of this post that will be used in the Series widget. Leave blank to use the full title.', 'publishpress-series-pro'); ?></p>
						<input type="text" name="serie_post_shorttitle[<?php echo $ser_id; ?>]" id="serie_post_shorttitle" style="width: 100%" value="<?php echo get_post_meta($id, SPOST_SHORTTITLE_KEY, true); ?>"/>
					</div>
					<input type="hidden" name="is_series_save" value="1"/>
				</div>
			</div><?php
		}

		function posts_custom_column_action($column_name, $id)
		{
			$seriesid = null;
			$series_part = null;
			$series_name = null;
			$post_types = apply_filters('orgseries_posttype_support', array('post'));
			if ($column_name == ppseries_get_series_slug()) {
				$column_content = "<div class=\"series_column\">\n";
				if ($series = get_the_series($id, false)) {
					$column_content .= "\t<ul class=\"ppseries-column-ul series-column\">\n";
					foreach ($series as $ser) {
						$id_arr[] = $seriesid = $ser->term_id;
						$sname_arr[] = $series_name = $ser->name;
						$spart_arr[] = $series_part = wp_series_part($id, $seriesid);
						$series_link = admin_url("edit.php?page=manage-issues&action=part&series_ID=" . $seriesid . "");
						
						$count = $ser->count;
						$column_content .= "\t\t<li class=\"series-column-li\">";

						$post_status = get_post_status($id);
						if (in_array($post_status, array('publish', 'private'))) {

							if (empty(trim($series_part))) {
								$column_content .= sprintf(__('<a href="%1$s" title="%2$s">%3$s</a> (No part number)', 'publishpress-series-pro'), $series_link, $series_name, $series_name);

							} else {
								$column_content .= sprintf(__('<a href="%3$s" title="%4$s">%5$s</a> (Part %1$s of %2$s)', 'publishpress-series-pro'), $series_part, $count, $series_link, $series_name, $series_name);
							}

						} else {
							$column_content .= sprintf(__('<a href="%1$s" title="%2$s">%3$s</a> (No Part Number)', 'publishpress-series-pro'), $series_link, $series_name, $series_name);
						}

						$column_content .= "</li>\n";
					}

					$column_content .= "\t</ul>\n";
					$seriesids = implode(',', $id_arr);
					$series_names = implode(',', $sname_arr);
					//$series_parts = implode(',', $spart_arr);
					$column_content .= "\t" . '<div class="hidden" id="inline_series_' . $id . '">';
					$column_content .= "\n\t\t" . '<div class="series_inline_edit">' . $seriesids . '</div>';

					for ($i = 0; $i < count($id_arr); $i++) {
						$column_content .= "\n\t\t" . '<div class="series_inline_part_' . $id_arr[$i] . '">' . $spart_arr[$i] . '</div>';
					}
					$column_content .= "\n\t\t" . '<div class="series_post_id">' . $id . '</div>';
					$column_content .= "\n\t\t" . '<div class="series_inline_name">' . $series_names . '</div>';
					$column_content .= "\n\t</div>\n";

				} else {
					$column_content .= "\t" . '<div class="hidden" id="inline_series_' . $id . '">';
					$column_content .= "\n\t\t" . '<div class="series_inline_edit"></div>';
					$column_content .= "\n\t\t" . '<div class="series_inline_part"></div>';
					$column_content .= "\n\t\t" . '<div class="series_post_id">' . $id . '</div>';
					$column_content .= "\n\t\t" . '<div class="series_inline_name"></div>';
					$column_content .= "\n\t</div>\n";
					$column_content .= '<em>' . esc_html__('No Series', 'publishpress-series-pro') . '</em>';
				}

				$column_content .= "</div>";
				echo $column_content;
			}
		}

	} //end class osMulti
} //end class check

/**
 * Directly taken and modified from WordPress -> Walker_Category_Checklist.  Needed to do this so I can insert the fields for setting the series part when there are multiple series.
 */
class Walker_SeriesChecklist extends Walker
{
	var $tree_type = 'series';
	var $db_fields = array('parent' => 'parent', 'id' => 'term_id');
	var $alt = 0;

	function start_el(&$output, $series, $depth = 0, $args = array(), $current_object_id = 0)
	{
		extract($args);
		$class = 'series-li ';
		$class .= in_array($series->term_id, $popular_series) ? 'popular-category' : '';
		$class .= ($this->alt & 1) ? ' odd' : '';
		$class = 'class="' . $class . '"';
		$series_part = array_key_exists($series->term_id, $series_parts) ? $series_parts[$series->term_id] : '';
		$output .= "\n<li id='series-{$series->term_id}'$class>" . '<div class="series-li-part"><div><label class="selectit"><input class="series-li-input" value="' . $series->term_id . '" type="checkbox" name="' . $name . '[]" id="in-series-' . $series->term_id . '"' . checked(in_array($series->term_id, $selected_series), true, false) . disabled(empty($args['disabled']), false, false) . ' /> ' . esc_html(apply_filters('list_series', $series->name, $series)) . '</label></div><div style="display: none;"><span class="to_series_part"><input id="series-part-' . $series->term_id . '" type="text" class="series_part" size="3" value="' . $series_part . '" name="series_part[' . $series->term_id . ']" /></span></div></div>';
		$this->alt++;
	}

	function end_el(&$output, $series, $depth = 0, $args = array())
	{
		$output .= "</li>\n";
	}
} //end Walker_SeriesChecklist class
