<?php

class Intense_Skins {
	function __construct() {
		add_action( 'wp_ajax_intense_shortcode_skin_settings_action', array( __CLASS__, 'ajax_shortcodes_action' ) );
		add_action( 'wp_ajax_intense_skins_list_action', array( __CLASS__, 'ajax_list' ) );
		add_action( 'wp_ajax_intense_skins_remove_action', array( __CLASS__, 'ajax_remove' ) );
		add_action( 'wp_ajax_intense_skins_add_action', array( __CLASS__, 'ajax_add' ) );
		add_action( 'wp_ajax_intense_skins_export_action', array( __CLASS__, 'ajax_export' ) );
		add_action( 'wp_ajax_intense_skins_edit_action', array( __CLASS__, 'ajax_edit' ) );
		add_action( 'wp_ajax_intense_skins_save_shortcode_action', array( __CLASS__, 'ajax_save_shortcode' ) );
	}

	public static function parse_atts( $m ) {
		global $attr;

		// allow [[foo]] syntax for escaping a tag
		if ( $m[1] == '[' && $m[6] == ']' ) {
			return substr( $m[0], 1, -1 );
		}

		$tag = $m[2];
		$attr = shortcode_parse_atts( $m[3] );

		return '';
	}

	public static function ajax_save_shortcode() {
		global $intense_skins;
		global $attr;

		// check for rights
		if ( !current_user_can( 'edit_pages' ) && !current_user_can( 'edit_posts' ) )
			die( __( "You are not allowed to be here" ) );

		check_ajax_referer( 'intense-plugin-noonce', 'security' );

		$skin = $intense_skins->load_skin( $_POST['key'] );
		$shortcode = $_POST['shortcode'];

		if ( !empty( $skin ) && !empty( $shortcode ) ) {
			preg_match( '/\[intense_[a-z_]+/', $shortcode, $matches );
			$shortcode_name = substr( $matches[0], 1 );

			//get attributes and values from shortcode
			$attr = null;

 			$shortcode = str_replace('\"', '"', $shortcode);

			$pattern = get_shortcode_regex();
			preg_replace_callback( "/$pattern/s",
				array( __CLASS__, 'parse_atts' ),
				$shortcode );

			$defaults = array();

			if ( !empty( $attr ) ) {						
				foreach ( $attr as $key => $value ) {					
					$defaults[ $key ] = trim( $value, "\"" );
				}
			}

			$skin->set_shortcode_defaults( $shortcode_name, $defaults );
			$skin->save();

			$results['status'] = 'Success';
			$results['message'] = 'Shortcode values were saved to the skin';
			$results['attr'] = $attr;
		} else {
			$results['status'] = 'Failed';
			$results['message'] = 'Skin Missing';
		}

		echo json_encode( $results );

		die();
	}

	public static function ajax_edit() {
		global $intense_skins;
		global $intense_shortcodes;

		check_ajax_referer( 'intense-plugin-noonce', 'security' );

		// check for rights
		if ( !current_user_can( 'edit_pages' ) && !current_user_can( 'edit_posts' ) )
			die( __( "You are not allowed to be here" ) );

		$skin = $intense_skins->load_skin( $_POST['key'] );

		if ( !empty( $skin ) ) {
			echo $intense_shortcodes->render_skin_settings();
			echo '<div id="intense-skin-shortcode-container">' . __( 'Select a shortcode', 'intense' ) . '</div>';
		} else {
			echo "Skin missing";
		}

		die();
	}

	public static function ajax_add() {
		global $intense_skins;

		check_ajax_referer( 'intense-plugin-noonce', 'security' );

		// check for rights
		if ( !current_user_can( 'edit_pages' ) && !current_user_can( 'edit_posts' ) )
			die( __( "You are not allowed to be here" ) );

		if ( !empty( $_POST['json'] ) ) {
			$skin = Intense_Skin::from_JSON( stripslashes( $_POST['json'] ) );

			if ( !empty( $_POST['key'] ) )
				$skin->key = $_POST['key'];

			if ( !empty( $_POST['name'] ) )
				$skin->name = $_POST['name'];
		} else {
			$skin = $intense_skins->load_skin( $_POST['key'] );
		}

		if ( empty( $skin ) ) {
			$skin = new Intense_Skin( $_POST['key'], $_POST['name'], array() );
		}

		$skin->save();

		die();
	}

	public static function ajax_export() {
		global $intense_skins;

		check_ajax_referer( 'intense-plugin-noonce', 'security' );

		// check for rights
		if ( !current_user_can( 'edit_pages' ) && !current_user_can( 'edit_posts' ) )
			die( __( "You are not allowed to be here" ) );

		$skin = $intense_skins->load_skin( $_POST['key'] );

		if ( !empty( $skin ) ) {
			unset( $skin->can_edit );
			unset( $skin->source_location );
			echo json_encode( $skin );
		} else {
			echo "Skin missing";
		}

		die();
	}

	public static function ajax_remove() {
		global $intense_skins;

		check_ajax_referer( 'intense-plugin-noonce', 'security' );

		// check for rights
		if ( !current_user_can( 'edit_pages' ) && !current_user_can( 'edit_posts' ) )
			die( __( "You are not allowed to be here" ) );

		$skin = $intense_skins->load_skin( $_POST['key'] );

		if ( !empty( $skin ) ) {
			$skin->remove();
		}

		die();
	}

	public static function ajax_list() {
		global $intense_skins;

		check_ajax_referer( 'intense-plugin-noonce', 'security' );

		// check for rights
		if ( !current_user_can( 'edit_pages' ) && !current_user_can( 'edit_posts' ) )
			die( __( "You are not allowed to be here" ) );


		echo json_encode( Intense_Skins::get_overridden_list() );

		die();
	}

	public static function get_overridden_list() {
		global $intense_skins;

		//Get the entire list then override accordingly
		//so the list returned is the overridden items
		$skins = $intense_skins->get_list();
		$skin_list = array();

		foreach ( $skins['Intense']['skins'] as $key => $value ) {
			$value->can_edit = false;
			$value->source_location = __( 'Intense', 'intense' );
			$skin_list[ $key ] = $value;
		}

		if ( !empty( $skins['Theme']['skins'] ) ) {
			foreach ( $skins['Theme']['skins'] as $key => $value ) {
				$value->can_edit = false;
				$value->source_location = __( 'Theme', 'intense' );
				$skin_list[ $key ] = $value;
			}
		}

		if ( !empty( $skins['Child Theme']['skins'] ) ) {
			foreach ( $skins['Child Theme']['skins'] as $key => $value ) {
				$value->can_edit = false;
				$value->source_location = __( 'Child Theme', 'intense' );
				$skin_list[ $key ] = $value;
			}
		}

		if ( !empty( $skins['Database']['skins'] ) ) {
			foreach ( $skins['Database']['skins'] as $key => $value ) {
				$value->can_edit = true;
				$value->source_location = __( 'Database', 'intense' );
				$skin_list[ $key ] = $value;
			}
		}

		return $skin_list;
	}

	function load_skin( $skin_key ) {
		if ( false === ( $skin = wp_cache_get( 'intense_skin_' . $skin_key ) ) ) {
			$skin = Intense_Skin::load( $skin_key );

			if ( empty( $skin ) ) {
				$skin = Intense_Skin::load_from_file( $this->get_location_path( 'Child Theme' ) . $skin_key . '.json' );
			}

			if ( empty( $skin ) ) {
				$skin = Intense_Skin::load_from_file( $this->get_location_path( 'Theme' ) . $skin_key . '.json' );
			}

			if ( empty( $skin ) ) {
				$skin = Intense_Skin::load_from_file( $this->get_location_path( 'Intense' ) . $skin_key . '.json' );
			}

			wp_cache_set( 'intense_skin_' . $skin_key, $skin );
		}

		return $skin;
	}

	function get_location_path( $location ) {
		$theme = wp_get_theme();

		switch ( $location ) {
		case 'Intense':
			return INTENSE_PLUGIN_FOLDER . '/skins/';
			break;
		case 'Theme':
			return get_template_directory() . '/intense_skins/';
			break;
		case 'Child Theme':
			return get_stylesheet_directory() . '/intense_skins/';
			break;
		}
	}

	function get_name( $path ) {
		return str_replace( ".json", "", substr( $path, strrpos( $path, "/" ) + 1 ) );
	}

	function get_list( ) {
		$theme = wp_get_theme();
		$plugin_files = array();
		$theme_files = array();
		$child_theme_files = array();
		$skins = array();

		$skins['Intense'] = array();
		$skins['Theme'] = array();
		$skins['Child Theme'] = array();
		$skins['Database'] = array();

		$this->find_in_directory( INTENSE_PLUGIN_FOLDER . '/skins/', null, $skins['Intense'] );
		$this->find_in_directory( get_template_directory() . '/intense_skins/', null, $skins[ 'Theme' ] );

		if ( get_stylesheet_directory() != get_template_directory() ) {
			$this->find_in_directory( get_stylesheet_directory() . '/intense_skins/', null, $skins['Child Theme'] );
		}

		//get skins from database
		$this->find_in_database( $skins['Database'] );

		return  $skins ;
	}

	function find_in_directory( $root, $path, &$skins ) {
		if ( $path == null ) $path = $root;

		$skins['skins'] = array();

		if ( is_dir( $path ) ) {
			$relative_path = str_replace( $root, '', $path );
			$paths = scandir( $path );
			$paths = array_flip( $paths );

			foreach ( $paths as $key => $value ) {
				if ( $key != '.' && $key != '..' && substr( $key, -strlen( ".json" ) ) == ".json" ) {
					$skins['skins'][ str_replace( ".json", "", $key ) ] = Intense_Skin::load_from_file( $path . '/' . $key );
				}
			}
		}
	}

	function find_in_database( &$skins ) {
		$db_skins = get_option( 'intense_skins' );

		$skins['skins'] = array();

		if ( $db_skins ) {
			foreach ( $db_skins as $key => $value ) {
				$skin = Intense_Skin::from_JSON( $value );
				$skins['skins'][ $key ] = $skin;
			}
		}
	}
}

class Intense_Skin {
	public $key;
	public $name;
	public $defaults;
	public $can_edit;
	public $source_location;

	public function __construct( $key, $name, $defaults ) {
		$this->key = $key;
		$this->name = $name;
		$this->defaults = $defaults;
	}

	public function set_shortcode_defaults( $shortcode, $defaults ) {
		$this->defaults[ $shortcode ] = $defaults;
	}

	public function get_shortcode_defaults( $shortcode ) {
		if ( isset( $this->defaults[ $shortcode ] ) ) {
			return $this->defaults[ $shortcode ];
		} else {
			return null;
		}
	}

	public function get_shortcode_default( $shortcode, $attr ) {
		if ( isset( $this->defaults[ $shortcode ][ $attr ] ) ) {
			return $this->defaults[ $shortcode ][ $attr ];
		} else {
			return null;
		}
	}

	/**
	 * CRUD
	 */

	public function save() {
		$db_skins = get_option( 'intense_skins' );

		if ( !$db_skins ) {
			$db_skins = array();
		}

		$db_skins[ $this->key ] = json_encode( $this );
		wp_cache_delete( 'intense_skin_' . $this->key );

		update_option( 'intense_skins', $db_skins );
	}

	public static function load( $key ) {
		$db_skins = get_option( 'intense_skins' );

		if ( $db_skins && !empty( $db_skins[ $key ] ) ) {
			$skin = Intense_Skin::from_JSON( $db_skins[ $key ] );

			return $skin;
		}

		return null;
	}

	public static function load_from_file( $path ) {
		if ( file_exists( $path ) ) {
			$skin_json = file_get_contents( $path );

			$skin = Intense_Skin::from_JSON( $skin_json );

			return $skin;
		}

		return null;
	}

	public function remove() {
		$db_skins = get_option( 'intense_skins' );

		unset( $db_skins[ $this->key ] );

		wp_cache_delete( 'intense_skin_' . $this->key );
		update_option( 'intense_skins', $db_skins );
	}

	public static function from_JSON( $json ) {
		$object = json_decode( $json, true );
		return new self( $object['key'], $object['name'], $object['defaults']  );
	}
}
