<?php
/**
 * The public-facing functionality of the plugin.
 *
 * @link       https://themehigh.com
 * @since      2.9.0
 *
 * @package    woocommerce-checkout-field-editor-pro
 * @subpackage woocommerce-checkout-field-editor-pro/public
 */
if(!defined('WPINC')){	die; }

if(!class_exists('THWCFE_Public_Checkout')):
 
class THWCFE_Public_Checkout extends THWCFE_Public {

	public function __construct( $plugin_name, $version ) {
		parent::__construct($plugin_name, $version);
		
		if(!isset($_SESSION)){
			session_start();
		}
		
		add_action('after_setup_theme', array($this, 'define_public_hooks'));
	}

	public function enqueue_styles_and_scripts() {
		global $wp_scripts;
		
		if(is_checkout()){
			$debug_mode = apply_filters('thwcfe_debug_mode', false);
			$in_footer  = apply_filters('thwcfe_enqueue_script_in_footer', true);
			
			$suffix = $debug_mode ? '' : '.min';
			$jquery_version = isset($wp_scripts->registered['jquery-ui-core']->ver) ? $wp_scripts->registered['jquery-ui-core']->ver : '1.9.2';
			
			$this->enqueue_styles($suffix, $jquery_version, $in_footer);
			$this->enqueue_scripts($suffix, $jquery_version, $in_footer);
		}
	}
	
	private function enqueue_styles($suffix, $jquery_version, $in_footer) {
		wp_enqueue_style('thwcfe-timepicker-style', THWCFE_ASSETS_URL_PUBLIC.'js/timepicker/jquery.timepicker.css');
		wp_enqueue_style('jquery-ui-style', '//ajax.googleapis.com/ajax/libs/jqueryui/'. $jquery_version .'/themes/smoothness/jquery-ui.css');
	}

	private function enqueue_scripts($suffix, $jquery_version, $in_footer) {
		wp_register_script('thwcfe-timepicker-script', THWCFE_ASSETS_URL_PUBLIC.'js/timepicker/jquery.timepicker.min.js', array('jquery'), '1.0.1', $in_footer);
		
		$deps = array();
		if( apply_filters( 'thwcfe_include_jquery_ui_i18n', TRUE ) ) {
			wp_register_script('jquery-ui-i18n', '//ajax.googleapis.com/ajax/libs/jqueryui/'.$jquery_version.'/i18n/jquery-ui-i18n.min.js',
			array('jquery','jquery-ui-datepicker'), $in_footer);
			
			$deps[] = 'jquery-ui-i18n';
		}else{
			$deps[] = 'jquery';
			$deps[] = 'jquery-ui-datepicker';
		}
		
		if(THWCFE_Utils::get_settings('disable_select2_for_select_fields') != 'yes'){
			$deps[] = 'select2';
		}
		
		wp_register_script('thwcfe-public-checkout-script', THWCFE_ASSETS_URL_PUBLIC.'js/thwcfe-public-checkout'. $suffix .'.js', $deps, TH_WCFE_VERSION, $in_footer);
		
		if(apply_filters('thwcfe_force_register_date_picker_script', false)){
			wp_register_script('thwcfe-datepicker-script', 'https://code.jquery.com/ui/'.$jquery_version.'/jquery-ui.js', array('jquery'), '1.0.1', $in_footer);
			wp_enqueue_script('thwcfe-datepicker-script');
		}
		
		wp_enqueue_script('thwcfe-timepicker-script');
		wp_enqueue_script('thwcfe-public-checkout-script');
		
		$enable_conditions_payment_shipping = THWCFE_Utils::get_settings('enable_conditions_payment_shipping') ? true : false;
			
		$wcfe_var = array(
			'lang' => array( 
						'am' => THWCFE_i18n::__t('am'), 
						'pm' => THWCFE_i18n::__t('pm'),  
						'AM' => THWCFE_i18n::__t('AM'), 
						'PM' => THWCFE_i18n::__t('PM'),
						'decimal' => THWCFE_i18n::__t('.'), 
						'mins' => THWCFE_i18n::__t('mins'), 
						'hr'   => THWCFE_i18n::__t('hr'), 
						'hrs'  => THWCFE_i18n::__t('hrs'),
					),
			'language' 	  => THWCFE_i18n::get_locale_code(),
			'date_format' => THWCFE_Utils::get_jquery_date_format(wc_date_format()),
			'readonly_date_field' => apply_filters('thwcfe_date_picker_field_readonly', true),
			'restrict_time_slots_for_same_day' => apply_filters( 'thwcfe_time_picker_restrict_slots_for_same_day', true ),
			'rebind_all_cfields' => apply_filters( 'thwcfe_enable_conditions_based_on_review_panel_fields', $enable_conditions_payment_shipping ),
			'ajax_url'    => admin_url( 'admin-ajax.php' ),
		);
		wp_localize_script('thwcfe-public-checkout-script', 'thwcfe_public_var', $wcfe_var);
	}
	
	public function define_public_hooks(){
		$advanced_settings = $this->get_advanced_settings();
		$hp_cf = apply_filters('thwcfd_woocommerce_checkout_fields_hook_priority', 1000);
		
		//Show Custome Fields in Checkout Page
		add_action('woocommerce_checkout_before_customer_details', array($this, 'woo_checkout_before_customer_details'));
		add_action('woocommerce_checkout_after_customer_details', array($this, 'woo_checkout_after_customer_details'));
		
		add_action('woocommerce_before_checkout_billing_form', array($this, 'woo_before_checkout_billing_form'));
		add_action('woocommerce_after_checkout_billing_form', array($this, 'woo_after_checkout_billing_form'));
		
		add_action('woocommerce_before_checkout_shipping_form', array($this, 'woo_before_checkout_shipping_form'));
		add_action('woocommerce_after_checkout_shipping_form', array($this, 'woo_after_checkout_shipping_form'));
		
		add_action('woocommerce_before_checkout_registration_form', array($this, 'woo_before_checkout_registration_form'));
		add_action('woocommerce_after_checkout_registration_form', array($this, 'woo_after_checkout_registration_form'));
		
		add_action('woocommerce_before_order_notes', array($this, 'woo_before_order_notes'));
		add_action('woocommerce_after_order_notes', array($this, 'woo_after_order_notes'));
		
		add_action('woocommerce_review_order_before_cart_contents', array($this, 'woo_review_order_before_cart_contents'));
		add_action('woocommerce_review_order_after_cart_contents', array($this, 'woo_review_order_after_cart_contents'));
		
		add_action('woocommerce_review_order_before_order_total', array($this, 'woo_review_order_before_order_total'));
		add_action('woocommerce_review_order_after_order_total', array($this, 'woo_review_order_after_order_total'));
		
		add_action('woocommerce_checkout_before_terms_and_conditions', array($this, 'woo_checkout_before_terms_and_conditions'));
		add_action('woocommerce_checkout_after_terms_and_conditions', array($this, 'woo_checkout_after_terms_and_conditions'));
		
		add_action('woocommerce_review_order_before_submit', array($this, 'woo_review_order_before_submit'));
		add_action('woocommerce_review_order_after_submit', array($this, 'woo_review_order_after_submit'));
		
		add_action('woocommerce_checkout_before_order_review', array($this, 'woo_checkout_before_order_review'));
		add_action('woocommerce_checkout_after_order_review', array($this, 'woo_checkout_after_order_review'));
		
		add_action('woocommerce_checkout_order_review', array($this, 'woo_checkout_order_review_0'), 0);
		add_action('woocommerce_checkout_order_review', array($this, 'woo_checkout_order_review_99'), 99);
		
		$this->render_sections_added_to_custom_positions();
		add_filter('woocommerce_enable_order_notes_field', array($this, 'woo_enable_order_notes_field'), 1000);
		
		// Checkout init
		add_filter('woocommerce_checkout_fields', array($this, 'woo_checkout_fields'), $hp_cf);
		add_filter('woocommerce_billing_fields', array($this, 'woo_billing_fields'), $hp_cf, 2);
		add_filter('woocommerce_shipping_fields', array($this, 'woo_shipping_fields'), $hp_cf, 2);
		add_filter('woocommerce_default_address_fields', array($this, 'woo_default_address_fields'), $hp_cf);
		add_filter('woocommerce_get_country_locale', array($this, 'woo_get_country_locale'), $hp_cf);
		add_filter('woocommerce_get_country_locale_base', array($this, 'woo_prepare_country_locale'), $hp_cf);
		add_filter('woocommerce_get_country_locale_default', array($this, 'woo_prepare_country_locale'), $hp_cf);
		
		//Checkout Process(Validate checkout fields, save user meta and save order meta
		add_action('woocommerce_checkout_process', array($this, 'woo_checkout_process'));
		add_action('woocommerce_after_checkout_validation', array($this, 'woo_checkout_fields_validation'), 10, 2); 
		add_action('woocommerce_checkout_update_user_meta', array($this, 'woo_checkout_update_user_meta'), 10, 2); 
		add_action('woocommerce_checkout_update_order_meta', array($this, 'woo_checkout_update_order_meta'), 10, 2);
	}
	
	/*****************************************
	******** HELPER FUNCTIONS - START ********
	*****************************************/
	/*public function require_shipping_address($posted){
		if((WC()->cart->ship_to_billing_address_only() || !empty($posted['shiptobilling']) || 
			(!WC()->cart->needs_shipping() && get_option('woocommerce_require_shipping_address') === 'no'))){
			return false;
		}
		return true;
	}*/
	
	public function get_cart_summary(){
		$items = WC()->cart->get_cart();
		
		$cart = array();
		$cart['products']   = array();
		$cart['categories'] = array();
		$cart['variations'] = array();
		
		foreach($items as $item => $values) { 
			$cart['products'][] = $values['product_id'];
			$cart['categories'] = array_merge($cart['categories'], $this->get_product_categories($values['product_id']));
			if($values['variation_id']){
				$cart['variations'][] = $values['variation_id'];
			}
		} 
		
		$cart['products']   = array_values($cart['products']);
		$cart['categories'] = apply_filters('thwcfe_cart_product_categories', array_values($cart['categories']));
		$cart['variations'] = array_values($cart['variations']);
		
		return $cart;
	}
	
	public function get_product_categories($product_id){
		$categories = array();
		$assigned_categories = wp_get_post_terms($product_id, 'product_cat');
		
		$ingnore_translation = apply_filters('thwcfe_ingnore_wpml_translation_for_product_category', false);
		$is_wpml_active = THWCFE_Utils::is_wpml_active();
		if($is_wpml_active && $ingnore_translation){
			global $sitepress;
			global $icl_adjust_id_url_filter_off;
			$orig_flag_value = $icl_adjust_id_url_filter_off;
			$icl_adjust_id_url_filter_off = true;
			$default_lang = $sitepress->get_default_language();
		}
		
		foreach($assigned_categories as $category){
			$parent_categories = get_ancestors( $category->term_id, 'product_cat' ); 
			if(is_array($parent_categories)){
				foreach($parent_categories as $pcat_id){
					$pcat = get_term( $pcat_id, 'product_cat' );
					$categories[] = $pcat->slug;
				}
			}
			
			$cat_slug = $category->slug;
			if($is_wpml_active && $ingnore_translation){
				$default_cat_id = icl_object_id($category->term_id, 'category', true, $default_lang);
				$default_cat = get_term($default_cat_id);
				$cat_slug = $default_cat->slug;
			}
			$categories[] = $cat_slug;
		}
		
		if($is_wpml_active && $ingnore_translation){
			$icl_adjust_id_url_filter_off = $orig_flag_value;
		}
		
		return $categories;
	}
	/*****************************************
	******** HELPER FUNCTIONS - END ********
	*****************************************/
	
	/********************************************************
	******** DISPLAY CUSTOM SECTIONS & FIELDS - START ******
	********************************************************/
	public function get_custom_sections_by_hook($hook_name){
		$section_hook_map = THWCFE_Utils::get_section_hook_map();
		
		$sections = false;
		if(is_array($section_hook_map) && isset($section_hook_map[$hook_name])){
			$sections = $section_hook_map[$hook_name];
		}	
						
		return empty($sections) ? false : $sections;
	}
	
	public function output_custom_section($sections, $checkout=false){
		if($sections && is_array($sections)){
			$cart = $this->get_cart_summary();
			
			foreach($sections as $sname){
				$section = THWCFE_Utils::get_checkout_section($sname);
				
				if(WCFE_Section_Utils::is_valid_section($section)){
					$fields = THWCFE_Utils::get_fieldset($section, $cart);
					
					if(is_array($fields) && sizeof($fields) > 0){
						$wrap_with_div = THWCFE_Utils::get_settings('wrap_custom_sections_with_div');
						
						if($wrap_with_div === 'yes'){
							$css_class = $section->get_property('cssclass');
							$css_class = !empty($css_class) ? str_replace(" ", "", $css_class) : '';
							$css_class = !empty($css_class) ? str_replace(",", " ", $css_class) : '';
							echo '<div class="thwcfe-checkout-section '. $css_class .' '. $section->get_property('name') .'" >';
						}						
						if($section->get_property('show_title')){
							echo WCFE_Section_Utils::get_title_html($section);
						}
						
						foreach($fields as $name => $field){
							if(!(isset($field['enabled']) && $field['enabled'] == false)) {
								$value = null;
								if($checkout instanceof WC_Checkout){
									$value = $checkout->get_value($name);
								}else if(is_array($checkout) && isset($checkout['post_data'])){
									$value = THWCFE_Utils::get_value_from_query_string($checkout['post_data'], $name);
								}
								
								if(!$value && is_user_logged_in() && isset($field['user_meta']) && $field['user_meta']){
									$current_user = wp_get_current_user();
									if(metadata_exists('user', $current_user->ID, $field['name'])){
										$value = get_user_meta($current_user->ID, $field['name'], true);
									}
								}
								
								woocommerce_form_field($name, $field, $value);
							}
						}
						
						if($wrap_with_div === 'yes'){
							echo '</div>';
						}
					}
				}
			}
		}
	}
		
	public function woo_before_checkout_form($checkout) {
		$sections = $this->get_custom_sections_by_hook('before_checkout_form');
		$this->output_custom_section($sections, $checkout);	
	}
	public function woo_after_checkout_form($checkout) {
		$sections = $this->get_custom_sections_by_hook('after_checkout_form');
		$this->output_custom_section($sections, $checkout);	
	}
	public function woo_checkout_before_customer_details() {
		$sections = $this->get_custom_sections_by_hook('before_customer_details');
		$this->output_custom_section($sections);	
	}
	public function woo_checkout_after_customer_details() {
		$this->output_disabled_field_names_hidden_field();
		
		$sections = $this->get_custom_sections_by_hook('after_customer_details');
		$this->output_custom_section($sections);	
	}
	public function woo_before_checkout_billing_form($checkout) {
		$sections = $this->get_custom_sections_by_hook('before_checkout_billing_form');
		$this->output_custom_section($sections, $checkout);	
	}
	public function woo_after_checkout_billing_form($checkout) {
		$sections = $this->get_custom_sections_by_hook('after_checkout_billing_form');
		$this->output_custom_section($sections, $checkout);	
	}
	public function woo_before_checkout_shipping_form($checkout) {
		$sections = $this->get_custom_sections_by_hook('before_checkout_shipping_form');
		$this->output_custom_section($sections, $checkout);	
	}
	public function woo_after_checkout_shipping_form($checkout) {
		$sections = $this->get_custom_sections_by_hook('after_checkout_shipping_form');
		$this->output_custom_section($sections, $checkout);	
	}
	public function woo_before_checkout_registration_form($checkout) {
		$sections = $this->get_custom_sections_by_hook('before_checkout_registration_form');
		$this->output_custom_section($sections, $checkout);	
	}
	public function woo_after_checkout_registration_form($checkout) {
		$sections = $this->get_custom_sections_by_hook('after_checkout_registration_form');
		$this->output_custom_section($sections, $checkout);	
	}
	public function woo_before_order_notes($checkout) {
		$sections = $this->get_custom_sections_by_hook('before_order_notes');
		$this->output_custom_section($sections, $checkout);	
	}		
	public function woo_after_order_notes($checkout) {	
		$sections = $this->get_custom_sections_by_hook('after_order_notes');
		$this->output_custom_section($sections, $checkout);	
	}	
	public function woo_review_order_before_cart_contents($checkout) {	
		$sections = $this->get_custom_sections_by_hook('before_cart_contents');
		$this->output_custom_section($sections, $checkout);	
	}	
	public function woo_review_order_after_cart_contents($checkout) {	
		$sections = $this->get_custom_sections_by_hook('after_cart_contents');
		$this->output_custom_section($sections, $checkout);	
	}	
	public function woo_review_order_before_order_total($checkout) {	
		$sections = $this->get_custom_sections_by_hook('before_order_total');
		$this->output_custom_section($sections, $checkout);	
	}	
	public function woo_review_order_after_order_total($checkout) {	
		$sections = $this->get_custom_sections_by_hook('after_order_total');
		$this->output_custom_section($sections, $checkout);	
	}	
	public function woo_checkout_before_terms_and_conditions($checkout) {	
		$sections = $this->get_custom_sections_by_hook('before_terms_and_conditions');
		$this->output_custom_section($sections, $_POST);	
	}	
	public function woo_checkout_after_terms_and_conditions($checkout) {	
		$sections = $this->get_custom_sections_by_hook('after_terms_and_conditions');
		$this->output_custom_section($sections, $_POST);	
	}	
	public function woo_review_order_before_submit($checkout) {	
		$sections = $this->get_custom_sections_by_hook('before_submit');
		$this->output_custom_section($sections, $_POST);	
	}	
	public function woo_review_order_after_submit($checkout) {	
		$sections = $this->get_custom_sections_by_hook('after_submit');
		$this->output_custom_section($sections, $_POST);	
	}	
	public function woo_checkout_before_order_review($checkout) {	
		$sections = $this->get_custom_sections_by_hook('before_order_review');
		$this->output_custom_section($sections, $checkout);	
	}	
	public function woo_checkout_after_order_review($checkout) {	
		$sections = $this->get_custom_sections_by_hook('after_order_review');
		$this->output_custom_section($sections, $checkout);	
	}	
	public function woo_checkout_order_review_0($checkout) {	
		$sections = $this->get_custom_sections_by_hook('order_review_0');
		$this->output_custom_section($sections, $checkout);	
	}	
	public function woo_checkout_order_review_99($checkout) {	
		$sections = $this->get_custom_sections_by_hook('order_review_99');
		$this->output_custom_section($sections, $checkout);	
	}
	
	public function render_sections_added_to_custom_positions(){
		$positions = apply_filters('thwcfe_custom_section_positions', array());
		if(is_array($positions)){
			foreach($positions as $hook_name => $label){
				add_action($hook_name, array($this, 'woo_checkout_custom_hook'));
			}
		}
	}
	public function woo_checkout_custom_hook($hook_name, $checkout=false){
		$sections = $this->get_custom_sections_by_hook($hook_name);
		$this->output_custom_section($sections, $checkout);
	}
	
	/* Hide Additional Fields title if no fields available. */
	public function woo_enable_order_notes_field() {
		$section = THWCFE_Utils::get_checkout_section('additional');
		if(WCFE_Section_Utils::is_valid_section($section)){
			$cart = $this->get_cart_summary();
			$fieldset = THWCFE_Utils::get_fieldset($section, $cart);
			
			if($fieldset){
				$enabled = 0;
				foreach($fieldset as $field){
					if($field['enabled']){
						//$enabled++;
						$enabled = 1;
						break;
					}
				}
				return $enabled > 0 ? true : false;
			}else{
				return false;
			}
		}
		return true;
	}
	
	public function woo_checkout_fields($checkout_fields){
		$sections = THWCFE_Utils::get_custom_sections();
		$cart = $this->get_cart_summary();
		
		foreach($sections as $sname => $section) {
			if($sname !== 'billing' && $sname !== 'shipping'){
				$fieldset = THWCFE_Utils::get_fieldset($section, $cart);
				$fieldset = $fieldset ? $fieldset : array();
				
				if(is_array($fieldset)){
					$sname = $sname === 'additional' ? 'order' : $sname;
					$checkout_fields[$sname] = $fieldset; //TODO merge instead repolacing existing fields to avoid losing any other non identified property
				}
			}
		}
		return $checkout_fields;
	}
	
	private function woo_address_fields($fields, $country, $section_name='billing'){
		$section_name = 'billing';
		$section = THWCFE_Utils::get_checkout_section($section_name);
		$use_default = apply_filters('thwcfe_use_default_fields_if_empty', true, $section_name);
		$cart = $this->get_cart_summary();
		
		if(WCFE_Section_Utils::is_valid_section($section)){
			if(is_wc_endpoint_url('edit-address')){  //TODO move to my account
				$fieldset = WCFE_Section_Utils::get_fieldset_all($section);
				if($fieldset || !$use_default){
					if(apply_filters('thwcfe_ignore_address_field_changes', false)) {
						$fieldset = $this->prepare_address_fields_my_account($fieldset, $fields, $section_name);
					}else{
						$fieldset = $this->prepare_address_fields($fieldset, $fields, $section_name, $country);
					}
					$fields = $fieldset;
				}
			}else{
				$fieldset = THWCFE_Utils::get_fieldset($section, $cart);
				if($fieldset || !$use_default){
					$fieldset = $this->prepare_address_fields($fieldset, $fields, $section_name, $country);
					$fields = $fieldset;
				}
			}
		}
		return $fields;
	}
	public function woo_billing_fields($fields, $country){
		return $this->woo_address_fields($fields, $country, 'billing');
	}
	public function woo_shipping_fields($fields, $country){
		return $this->woo_address_fields($fields, $country, 'shipping');
	}
	
	public function woo_default_address_fields($fields){
		$sname = apply_filters('thwcfe_address_field_override_with', 'billing');
		if($sname === 'billing' || $sname === 'shipping'){
			$section = THWCFE_Utils::get_checkout_section($sname);
			
			if(WCFE_Section_Utils::is_valid_section($section)){
				$address_fields = THWCFE_Utils::get_fieldset($section, $this->get_cart_summary());
				
				foreach($fields as $name => $field) {
					if(THWCFE_Utils::is_default_address_field($name)){
						$custom_field = isset($address_fields[$sname.'_'.$name]) ? $address_fields[$sname.'_'.$name] : false;
						
						if($custom_field && !( isset($custom_field['enabled']) && $custom_field['enabled'] == false )){
							$fields[$name]['required'] = isset($custom_field['required']) && $custom_field['required'] ? true : false;
						}
					}
				}
			}
		}
		return $fields;
	}
	
	public function woo_get_country_locale($locale) {
		if(is_array($locale)){
			foreach($locale as $country => $fields){
				$locale[$country] = $this->woo_prepare_country_locale($fields, $country);
			}
		}
		return $locale;
	}
	
	public function woo_prepare_country_locale($fields, $country=false) {
		if(is_array($fields)){
			$override_ph = apply_filters('thwcfe_address_field_override_placeholder', true, $country);
			$override_label = apply_filters('thwcfe_address_field_override_label', true, $country);
			$override_required = apply_filters('thwcfe_address_field_override_required', false, $country);
			$override_priority = apply_filters('thwcfe_address_field_override_priority', true, $country);
				
			foreach($fields as $key => $props){
				if($override_ph && isset($props['placeholder'])){
					unset($fields[$key]['placeholder']);
				}
				if($override_label && isset($props['label'])){
					unset($fields[$key]['label']);
				}
				if($override_required && isset($props['required'])){
					unset($fields[$key]['required']);
				}
				
				if($override_priority && isset($props['priority'])){
					unset($fields[$key]['priority']);
				}
			}
		}
		return $fields;
	}
    /*********************************************************
	******** DISPLAY CUSTOM SECTIONS & FIELDS - END **********
	*********************************************************/
	
	/*******************************************
	******** CHECKOUT PROCESS - START **********
	*******************************************/
	// Prepare Checkout Fields
	public function woo_checkout_process(){
		$disabled_fields = isset( $_POST['thwcfe_disabled_fields'] ) ? wc_clean( $_POST['thwcfe_disabled_fields'] ) : '';
		$dis_fields = $disabled_fields ? explode(",", $disabled_fields) : false;
		
		$dis_sections = array();
		$dis_hooks = array();
		
		$ship_to_different_address = isset($_POST['ship_to_different_address']) ? $_POST['ship_to_different_address'] : false;
		
		if(($ship_to_different_address == false || ! WC()->cart->needs_shipping_address())){
			$dis_hooks = array_merge($dis_hooks, array('before_checkout_shipping_form','after_checkout_shipping_form'));
		}		
		if(is_user_logged_in()){
			$dis_hooks = array_merge($dis_hooks, array('before_checkout_registration_form','after_checkout_registration_form'));
		}		
		if(!(isset($_POST['terms-field']) && $_POST['terms-field'])){
			$dis_hooks = array_merge($dis_hooks, array('before_terms_and_conditions','after_terms_and_conditions'));
		}
		
		if(!empty($dis_hooks)){
			foreach($dis_hooks as $hname){
				$hooked_sections = $this->get_custom_sections_by_hook($hname);
				if(is_array($hooked_sections)){
					foreach($hooked_sections as $sname){
						if(!in_array($sname, WCFE_Section_Utils::$DEFAULT_SECTIONS)){
							$dis_sections[] = $sname;
						}
					}
				}
			}
		}
			
		if( (is_array($dis_fields) && !empty($dis_fields)) || (is_array($dis_sections) && !empty($dis_sections)) ){
			$checkout_fields = WC()->checkout->checkout_fields;
			$modified = false;
			
			if(is_array($checkout_fields)){
				foreach($checkout_fields as $fieldset_key => $fieldset) {
					if(in_array($fieldset_key, $dis_sections)){
						unset($checkout_fields[$fieldset_key]);
						$modified = true;
						continue;
					}
				
					foreach($dis_fields as $fname){
						if(isset($fieldset[$fname])){
							unset($checkout_fields[$fieldset_key][$fname]);
							$modified = true;
						}
					}
				}
			}
			
			if($modified){
				WC()->checkout->checkout_fields = $checkout_fields;
			}
		}
	}
	
	// Validate Checkout Fields
	public function woo_checkout_fields_validation($posted, $errors){
		$checkout_fields = WC()->checkout->checkout_fields;
		
		foreach($checkout_fields as $fieldset_key => $fieldset){
			$ship_to_different_address = isset($posted['ship_to_different_address']) ? $posted['ship_to_different_address'] : false;
			
			if($fieldset_key == 'shipping' && ($ship_to_different_address == false || ! WC()->cart->needs_shipping_address())){
				continue;
			}
				
			foreach($fieldset as $key => $field) {
				//Fix for checkbox field required validation issue				
				/*if(isset($field['custom']) && $field['custom'] && isset($field['type']) && $field['type'] === 'checkbox'){	
					if(isset($field['required']) && $field['required'] && ( !isset($posted[$key]) || !$posted[$key]) ){
						wc_add_notice( apply_filters( 'woocommerce_checkout_required_field_notice', sprintf( _x( '%s is a required field.', 
						'FIELDNAME is a required field.', 'woocommerce' ), '<strong>' . $field['label'] . '</strong>' ), $field['label'] ), 'error' );
					}
				}*/
						
				if(isset($posted[$key]) && !THWCFE_Utils::is_blank($posted[$key])){
					$value = $posted[$key];
					$validate = isset($field['validate']) ? $field['validate'] : '';
					
					if(is_array($validate) && !empty($validate)){
						foreach($validate as $rule){
							switch($rule) {
								case 'number' :
									if(!is_numeric($value)){
										$err_msg = '<strong>'. THWCFE_i18n::__t($field['label']) .'</strong> '. THWCFE_i18n::__t( 'is not a valid number.' );							
										$this->wcfe_add_error($err_msg, $errors);
									}
									break;
								default:
									$custom_validators = THWCFE_Utils::get_settings('custom_validators');
									$validator = is_array($custom_validators) && isset($custom_validators[$rule]) ? $custom_validators[$rule] : false;
									if(is_array($validator)){
										$pattern = $validator['pattern'];
										
										if(preg_match($pattern, $value) === 0) {
											$err_msg = sprintf( THWCFE_i18n::__t( $validator['message'] ), THWCFE_i18n::__t($field['label']) );
											$this->wcfe_add_error($err_msg, $errors);
										}
										break;
									}else{
										$con_validators = THWCFE_Utils::get_settings('confirm_validators');
										$cnf_validator = is_array($con_validators) && isset($con_validators[$rule]) ? $con_validators[$rule] : false;
										if(is_array($cnf_validator)){
											$cfield = $cnf_validator['pattern'];
											$cvalue = $posted[$cfield];
											
											if($value && $cvalue && $value != $cvalue) {
												$err_msg = sprintf( THWCFE_i18n::__t( $cnf_validator['message'] ), THWCFE_i18n::__t($field['label']) );
												$this->wcfe_add_error($err_msg, $errors);
											}
											break;
										}
									}
							}
						}
					}
				}
			}
		}
	}
	
	// Save User Meta
	public function woo_checkout_update_user_meta($customer_id, $posted){
		$checkout_fields = WC()->checkout->checkout_fields;
		
		foreach($checkout_fields as $fieldset_key => $fieldset){
			if($fieldset_key === 'shipping' && !WC()->cart->needs_shipping()){
				continue;
			}
			
			foreach($fieldset as $key => $field) {
				if(isset($field['custom']) && $field['custom'] && isset($posted[$key])){	
					if(isset($field['user_meta']) && $field['user_meta']){
						$value  = $posted[$key];
						$value  = is_array($value) ? implode(",", $value) : $value;
						$fvalue = $field['default'];
						
						if($field['type'] === 'checkbox' && !empty($field['on_value'])){
							$value = $value == 1 ? $field['on_value'] : ''; 
						}
						
						$value = apply_filters( 'thwcfe_woocommerce_checkout_user_meta_posted_value_'.$key, $value, $customer_id, $posted );
						update_user_meta($customer_id, $key, $value );
					}
				}
			}
		}
	}
	
	// Save Order Meta
	public function woo_checkout_update_order_meta($order_id, $posted){
		$checkout_fields = WC()->checkout->checkout_fields;
		$ship_to_different_address = isset($posted['ship_to_different_address']) ? $posted['ship_to_different_address'] : false;
		
		if(!$ship_to_different_address || !WC()->cart->needs_shipping_address()){
			update_post_meta($order_id, 'thwcfe_ship_to_billing', 1);
		}else{
			update_post_meta($order_id, 'thwcfe_ship_to_billing', 0);
		}
		
		$disabled_fields = isset( $_POST['thwcfe_disabled_fields'] ) ? wc_clean( $_POST['thwcfe_disabled_fields'] ) : '';
		if($disabled_fields){
			$dis_fields = $disabled_fields ? explode(",", $disabled_fields) : false;
			if(is_array($dis_fields) && !empty($dis_fields)){
				$dis_fields = array_unique($dis_fields);
				$dis_fields = implode(",", $dis_fields);
				update_post_meta($order_id, '_thwcfe_disabled_fields', $dis_fields);
			}
		}
		
		foreach($checkout_fields as $fieldset_key => $fieldset){
			if($fieldset_key === 'shipping' && (!$ship_to_different_address || !WC()->cart->needs_shipping_address())){
				continue;
			}
			
			foreach($fieldset as $key => $field) {
				if(isset($field['custom']) && $field['custom'] && isset($posted[$key]) && !empty($posted[$key])){	
					if(isset($field['order_meta']) && $field['order_meta']){
						$value  = $posted[$key];
						$value  = is_array($value) ? implode(",", $value) : $value;
						$fvalue = $field['default'];
						
						if($field['type'] === 'checkbox' && !empty($field['on_value'])){
							$value = $value == 1 ? $field['on_value'] : ''; 
							/*$values = explode("|", $fvalue);
							if(is_array($values)){
								$true_val = isset($values[0]) ? $values[0] : '';
								$false_val = isset($values[1]) ? $values[1] : '';
								$value = $value == 1 ? $true_val : $false_val; 
							}*/
						}
						
						$value = apply_filters( 'thwcfe_woocommerce_checkout_order_meta_posted_value_'.$key, $value, $order_id, $posted );
						update_post_meta($order_id, $key, $value);
					}
				}
			}
		}
	}
	/*******************************************
	******** CHECKOUT PROCESS - END ************
	*******************************************/
	
	/*******************************************
	******** PRICE CALCULATION - START *********
	********************************************/
	public function validate_and_filter_fields($price_infos) {
		if($price_infos && is_array($price_infos)){
			$checkout_fields = $this->get_all_checkout_fields_map();
			
			if(!empty($checkout_fields)){
				$f_labels = array();
				
				foreach($price_infos as $name => $price_info){
					$field = isset($checkout_fields[$name]) && is_array($checkout_fields[$name]) ? $checkout_fields[$name] : false;
					if($field){
						$value = isset($price_info['value']) && !empty($price_info['value']) ? trim($price_info['value']) : '';
						$valid = $this->validate_field($name, $value, $field);
						
						$label = $price_info['label'];
						if(in_array($label, $f_labels)){
							$label = $name.'_'.$label;
						}
						$f_labels[] = $label;
						$price_infos[$name]['label'] = $label;
						
						if(!$valid){
							unset($price_infos[$name]);
						}
					}
				}
			}
		}
		return $price_infos;
	}
	
	// Validate Checkout Fields
	public function validate_field($name, $value, $field){
		$valid = true;
		if($value && !$this->is_blank($value)){
			$validation = isset($field['validate']) ? $field['validate'] : '';
			
			if(is_array($validation) && !empty($validation)){
				foreach($validation as $rule){
					switch($rule) {
						case 'number' :
							if(!is_numeric($value)){
								$valid = false;
							}
							break;
						default:
							$custom_validators = $this->get_settings('custom_validators');
							$validator = is_array($custom_validators) && isset($custom_validators[$rule]) ? $custom_validators[$rule] : false;
							if(is_array($validator)){
								$pattern = $validator['pattern'];
								
								if(preg_match($pattern, $value) === 0) {
									$valid = false;
								}
								break;
							}
					}
				}
			}
		}
		return $valid;
	}
	/*******************************************
	******** PRICE CALCULATION - END ***********
	********************************************/
	
}

endif;