<?php
final class NBTWCCS {
    public $storage = null;
    public $cron = NULL;
    public $cron_hook = 'nbtwccs_update_rates_wpcron';
    public $wp_cron_period = DAY_IN_SECONDS;
    public $settings = array();
    public $fixed = NULL;
    public $fixed_coupon = NULL;
    public $fixed_shipping = NULL;
    public $fixed_shipping_free = NULL;
    public $default_currency = 'USD'; //EUR -> set any existed currency here if USD is not exists in your currencies list
    public $current_currency = 'USD'; //EUR -> set any existed currency here if USD is not exists in your currencies list
    public $currency_positions = array();
    public $currency_symbols = array();
    public $is_multiple_allowed = false; //from options
    public $is_fixed_enabled = false; //from options, works if is_multiple_allowed enabled
    public $is_fixed_coupon = false;
    public $is_fixed_shipping = false;
    public $is_fixed_shipping_free = false;
    public $force_pay_bygeoip_rules = false; //from options, works if is_fixed_enabled enabled
    public $is_geoip_manipulation = true; //from options, works if is_multiple_allowed is NOT enabled
    public $decimal_sep = '.';
    public $thousands_sep = ',';
    public $rate_auto_update = ''; //from options
    public $shop_is_cached = true;
    private $is_first_unique_visit = false;
    public $no_cents = array('JPY', 'TWD'); //recount price without cents always!!
    public $price_num_decimals = 2;
    public $actualized_for = 0; //created especially for woo >= 2.7 as it not possible to use const WOOCOMMERCE_VERSION in the code at some places
    public $bones = array(
        'reset_in_multiple' => false, //normal is false
        'disable_currency_switching' => false//normal is false. To force the customer to pay in Welcome currency for example, do it by your own logic
    ); //just for some setting for current wp theme adapting - for support only - it is logic hack - be care!!

    public function __construct() {
        $this->storage = new NBTWCCS_STORAGE(get_option('nbtwccs_storage', 'transient'));
        
        if (!defined('DOING_AJAX')) {
        //we need it if shop uses cache plugin, in such way prices will be redraw by AJAX
            $this->shop_is_cached = get_option('nbtwccs_shop_is_cached', 0);
        }

        //need for woo 2.7
        $this->actualized_for = floatval(WOOCOMMERCE_VERSION);

        add_filter('pre_option_woocommerce_price_num_decimals', array($this, 'woocommerce_price_num_decimals'));
        
        if (version_compare($this->actualized_for, 3.6, '>=')) {
            add_filter('woocommerce_cart_hash', array($this, 'woocommerce_add_to_cart_hash'), 2, 99999);
        } else {
            add_filter('woocommerce_add_to_cart_hash', array($this, 'woocommerce_add_to_cart_hash'));
        }

        add_action('wp_enqueue_scripts', array($this, 'disable_woo_slider_script'), 100);
        $currencies = $this->get_currencies();
        if (!empty($currencies) AND is_array($currencies)) {
            foreach ($currencies as $key => $currency) {
                if ($currency['is_etalon']) {
                    $this->default_currency = $key;
                    break;
                }
            }
        }

/*        $this->is_geoip_manipulation = get_option('nbtwccs_is_geoip_manipulation', 0);*/
        $this->is_multiple_allowed = get_option('nbtwccs_is_multiple_allowed', 0);
        if ($this->is_geoip_manipulation) {
            $this->is_multiple_allowed = true;
        }
/*        $this->is_fixed_enabled = get_option('nbtwccs_is_fixed_enabled', 0);
        $this->is_fixed_coupon = get_option('nbtwccs_is_fixed_coupon', 0);
        $this->is_fixed_shipping = get_option('nbtwccs_is_fixed_shipping', 0);
        $this->is_fixed_shipping_free = get_option('nbtwccs_is_fixed_shipping', 0);*/

        $this->force_pay_bygeoip_rules = get_option('nbtwccs_force_pay_bygeoip_rules', 0);
        $this->rate_auto_update = get_option('nbtwccs_currencies_rate_auto_update', 'no');

        $this->currency_positions = array('left', 'right', 'left_space', 'right_space');
        $this->init_currency_symbols();
        $is_first_activation = (int) get_option('nbtwccs_first_activation', 0);
        if (!$is_first_activation) {
            update_option('nbtwccs_first_activation', 1);
            update_option('nbtwccs_drop_down_view', 'no');
            update_option('nbtwccs_currencies_aggregator', 'google');
            update_option('nbtwccs_welcome_currency', $this->default_currency);
            update_option('nbtwccs_is_multiple_allowed', 0);
/*            update_option('nbtwccs_is_fixed_enabled', 0);*/
/*            update_option('nbtwccs_is_fixed_shipping', 0);
            update_option('nbtwccs_is_fixed_coupon', 0);
            update_option('nbtwccs_force_pay_bygeoip_rules', 0);*/
/*            update_option('nbtwccs_is_geoip_manipulation', 0);*/
/*            update_option('nbtwccs_show_flags', 1);*/
            update_option('nbtwccs_show_money_signs', 1);
/*            update_option('nbtwccs_customer_signs', '');*/
/*            update_option('nbtwccs_customer_price_format', '');*/
            update_option('nbtwccs_currencies_rate_auto_update', 'no');

            //update_option('nbtwccs_use_curl', 0);
            update_option('nbtwccs_storage', 'transient');
            update_option('nbtwccs_geo_rules', '');
            //update_option('nbtwccs_use_geo_rules', 0);
            update_option('nbtwccs_hide_cents', '');
            update_option('nbtwccs_decimals', array());
/*            update_option('nbtwccs_price_info', 0);*/
/*            update_option('nbtwccs_no_cents', '');*/
            update_option('nbtwccs_restrike_on_checkout_page', 0);
            update_option('nbtwccs_shop_is_cached', 0);
            update_option('nbtwccs_show_approximate_amount', 0);
            $this->reset_currency();
            
            update_option('image_default_link_type', 'file'); //http://wordpress.stackexchange.com/questions/9727/link-to-file-url-by-default
        }

//simple checkout itercept
        if (isset($_REQUEST['action']) AND $_REQUEST['action'] == 'woocommerce_checkout') {
            $_REQUEST['woocommerce-currency-switcher'] = $this->escape($this->storage->get_val('nbtwccs_current_currency'));
            $this->current_currency = $this->escape($this->storage->get_val('nbtwccs_current_currency'));
            $_REQUEST['nbtwccs_in_order_currency'] = $this->current_currency;
        }

//paypal query itercept
        if (isset($_REQUEST['mc_currency']) AND ! empty($_REQUEST['mc_currency'])) {
            if (array_key_exists($_REQUEST['mc_currency'], $currencies)) {
                $_REQUEST['woocommerce-currency-switcher'] = $this->escape($_REQUEST['mc_currency']);
            }
        }

//WELCOME USER CURRENCY ACTIVATION
        if (intval($this->storage->get_val('nbtwccs_first_unique_visit')) === 0) {
            $this->is_first_unique_visit = true;
            $this->set_currency($this->get_welcome_currency());
            $this->storage->set_val('nbtwccs_first_unique_visit', 1);
        }
        if (isset($_REQUEST['woocommerce-currency-switcher'])) {
            if (array_key_exists($_REQUEST['woocommerce-currency-switcher'], $currencies)) {
                $this->storage->set_val('nbtwccs_current_currency', $this->escape($_REQUEST['woocommerce-currency-switcher']));
            } else {
                $this->storage->set_val('nbtwccs_current_currency', $this->default_currency);
            }
        }
//*** check currency in browser address
        if (isset($_GET['currency']) AND ! empty($_GET['currency'])) {
            $allow_currency_switching = !$this->bones['disable_currency_switching'];

            //1 issue closing
            if (!get_option('nbtwccs_is_multiple_allowed', 0)) {
                if (isset($_REQUEST['wc-ajax']) AND ( $_REQUEST['wc-ajax'] == 'get_refreshed_fragments' OR $_REQUEST['wc-ajax'] == 'update_order_review')) {
                    if (isset($_SERVER['REQUEST_URI'])) {
                        if (substr_count($_SERVER['REQUEST_URI'], '/checkout/')) {
                            $allow_currency_switching = false;
                            $this->reset_currency();
                        }
                    }
                }
            }

            if (array_key_exists(strtoupper($_GET['currency']), $currencies) AND $allow_currency_switching) {
                $this->storage->set_val('nbtwccs_current_currency', strtoupper($this->escape($_GET['currency'])));
            }
        }

        if ($this->storage->is_isset('nbtwccs_current_currency')) {
            $this->current_currency = $this->storage->get_val('nbtwccs_current_currency');
        } else {
            $this->current_currency = $this->default_currency;
        }
        $this->storage->set_val('nbtwccs_default_currency', $this->default_currency);

        //if we want to be paid in the basic currency - not multiple mode
        if (isset($_REQUEST['action']) AND ! get_option('nbtwccs_is_multiple_allowed', 0)) {
            //old code for woocomerce < 2.4, left for comatibility with old versions of woocommerce
            if ($_REQUEST['action'] == 'woocommerce_update_order_review') {
                $this->reset_currency();
            }
        }

//+++ FILTERS
        add_filter('woocommerce_paypal_args', array($this, 'apply_conversion'));
        add_filter('woocommerce_paypal_supported_currencies', array($this, 'enable_custom_currency'), 9999);
        add_filter('woocommerce_currency_symbol', array($this, 'woocommerce_currency_symbol'), 9999);
        add_filter('woocommerce_currency', array($this, 'get_woocommerce_currency'), 9999);
        add_filter('wc_get_template', array($this, 'wc_get_template'), 9999, 5); //from woo 2.7 its nessesary for new order email
//fix woo 3.3.0
        if ($this->is_multiple_allowed) {
            add_action('woocommerce_coupon_loaded', array($this, 'woocommerce_coupon_loaded'), 9999);
        }
//main recount hook
        if ($this->is_multiple_allowed) {
            //woo >= v.2.7
            add_filter('woocommerce_product_get_price', array($this, 'raw_woocommerce_price'), 9999, 2);
            //wp-content\plugins\woocommerce\includes\abstracts\abstract-wc-data.php
            //protected function get_prop
            add_filter('woocommerce_product_variation_get_price', array($this, 'raw_woocommerce_price'), 9999, 2);
            add_filter('woocommerce_product_variation_get_regular_price', array($this, 'raw_woocommerce_price'), 9999, 2);
            //for correct currency in preview html
            add_filter('woocommerce_admin_order_preview_line_items', array($this, 'woocommerce_admin_order_preview_line_items'), 9999, 2);
            //comment next code line if on single product page for variable prices you see crossed out price which equal to the regular one,
            //I mean you see 2 same prices (amounts) and one of them is crossed out which by logic should not be visible at all
            //add_filter('woocommerce_product_variation_get_sale_price', array($this, 'raw_woocommerce_price'), 9999, 2);
            //new  function  for sale price
            add_filter('woocommerce_product_variation_get_sale_price', array($this, 'raw_sale_price_filter'), 9999, 2);
        } else {
            add_filter('raw_woocommerce_price', array($this, 'raw_woocommerce_price'), 9999);
        }
        if ($this->is_multiple_allowed) {
            //woo >= v.2.7
            add_filter('woocommerce_product_get_regular_price', array($this, 'raw_woocommerce_price'), 9999, 2);

            //woo >= v.2.7
            add_filter('woocommerce_product_get_sale_price', array($this, 'raw_woocommerce_price_sale'), 9999, 2);

            add_filter('woocommerce_get_variation_regular_price', array($this, 'raw_woocommerce_price'), 9999, 4);
            add_filter('woocommerce_get_variation_sale_price', array($this, 'raw_woocommerce_price'), 9999, 4);
            add_filter('woocommerce_variation_prices', array($this, 'woocommerce_variation_prices'), 9999, 3);

            add_filter('woocommerce_get_variation_prices_hash', array($this, 'woocommerce_get_variation_prices_hash'), 9999, 3);

        }

        add_filter('woocommerce_price_format', array($this, 'woocommerce_price_format'), 9999);
        add_filter('woocommerce_thankyou_order_id', array($this, 'woocommerce_thankyou_order_id'), 9999);
        add_filter('woocommerce_before_resend_order_emails', array($this, 'woocommerce_before_resend_order_emails'), 1);
        add_filter('woocommerce_email_actions', array($this, 'woocommerce_email_actions'), 10);
        add_action('woocommerce_order_status_completed', array($this, 'woocommerce_order_status_completed'), 1);
        add_action('woocommerce_order_status_completed_notification', array($this, 'woocommerce_order_status_completed_notification'), 1);

        add_filter('woocommerce_package_rates', array($this, 'woocommerce_package_rates'), 9999);


//for shop cart
        add_filter('woocommerce_cart_totals_order_total_html', array($this, 'woocommerce_cart_totals_order_total_html'), 9999, 1);
        add_filter('wc_price_args', array($this, 'wc_price_args'), 9999);


//for refreshing mini-cart widget
        add_filter('woocommerce_before_mini_cart', array($this, 'woocommerce_before_mini_cart'), 9999);
        add_filter('woocommerce_after_mini_cart', array($this, 'woocommerce_after_mini_cart'), 9999);

//shipping
        add_filter('woocommerce_shipping_free_shipping_is_available', array($this, 'woocommerce_shipping_free_shipping_is_available'), 999, 3);
        add_filter('woocommerce_shipping_legacy_free_shipping_is_available', array($this, 'woocommerce_shipping_free_shipping_is_available'), 999, 3);

        add_action('woocommerce_get_order_currency', array($this, 'woocommerce_get_order_currency'), 1, 2);


//+++ AJAX ACTIONS
        add_action('woocommerce_before_calculate_totals', array($this, 'nbtwccs_before_calculate_totals_geoip_fix'));

        add_action('wp_ajax_nbtwccs_save_etalon', array($this, 'save_etalon'));
        add_action('wp_ajax_nbtwccs_get_rate', array($this, 'get_rate'));

        add_action('wp_ajax_nbtwccs_convert_currency', array($this, 'nbtwccs_convert_currency'));
        add_action('wp_ajax_nopriv_nbtwccs_convert_currency', array($this, 'nbtwccs_convert_currency'));

        add_action('wp_ajax_nbtwccs_rates_current_currency', array($this, 'nbtwccs_rates_current_currency'));
        add_action('wp_ajax_nopriv_nbtwccs_rates_current_currency', array($this, 'nbtwccs_rates_current_currency'));

        add_action('wp_ajax_nbtwccs_get_products_price_html', array($this, 'nbtwccs_get_products_price_html'));
        add_action('wp_ajax_nopriv_nbtwccs_get_products_price_html', array($this, 'nbtwccs_get_products_price_html'));

        add_action('wp_ajax_nbtwccs_recalculate_order_data', array($this, 'nbtwccs_recalculate_order_data'));        
        add_action('admin_menu', array($this, 'register_subpage_media1'));
        //fix for checkout 14.11.17
        add_action('woocommerce_checkout_process', array($this, 'check_currency_on_checkout'), 1);

        add_action('wp_head', array($this, 'wp_head'), 999);
        add_action('wp_footer', array($this, 'wp_footer'), 9999);
        add_action('body_class', array($this, 'body_class'), 9999);

        add_action('save_post', array($this, 'save_post'), 1);
        add_action('admin_head', array($this, 'admin_head'), 1);
       
        add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts'));
        add_action('admin_init', array($this, 'admin_init'), 1);
        add_filter( 'walker_nav_menu_start_el', array( $this, 'nbt_start_el' ), 20, 2 );
        // Making it work with Max Mega Menu Plugin.
            add_filter( 'megamenu_walker_nav_menu_start_el', array( $this, 'nbt_start_el' ), 20, 2 );
//price formatting on front ***********

        add_action('woocommerce_get_price_html', array($this, 'woocommerce_price_html'), 1, 2);
        add_action('woocommerce_variable_sale_price_html', array($this, 'woocommerce_price_html'), 1, 2);
        add_action('woocommerce_sale_price_html', array($this, 'woocommerce_price_html'), 1, 2);
        add_action('woocommerce_grouped_price_html', array($this, 'woocommerce_price_html'), 1, 2);


//*** additional

        add_action('wpo_wcpdf_process_template_order', array($this, 'wpo_wcpdf_process_template_order'), 1, 2);
        add_action('nbtwccs_exchange_value', array($this, 'nbtwccs_exchange_value'), 1);

        add_filter('woocommerce_checkout_update_order_review', array($this, 'woocommerce_checkout_update_order_review'), 9999);

        //fix  for  calculate shipping with  cost arguments
        add_filter("woocommerce_evaluate_shipping_cost_args", array($this, "woocommerce_fix_shipping_calc"), 10, 3);
        //fix  if current and basic  currencies have different decimsls
        add_filter('wc_get_price_decimals', array($this, 'nbtwccs_fix_decimals'), 999);


//*** comment it!!! It is custom work experiments ....
        add_shortcode('nbt_currency_switcher', array($this, 'nbtwccs_shortcode'));
        add_shortcode('nbtwccs_get_sign_rate', array($this, 'get_sign_rate'));
        add_shortcode('nbtwccs_converter', array($this, 'nbtwccs_converter'));
        add_shortcode('nbtwccs_rates', array($this, 'nbtwccs_rates'));
        add_shortcode('nbtwccs_show_current_currency', array($this, 'nbtwccs_show_current_currency'));
        add_shortcode('nbtwccs_show_custom_price', array($this, 'nbtwccs_show_custom_price'));
        add_shortcode('nbtwccs_geo_hello', array($this, 'nbtwccs_geo_hello'));

        if (get_option('nbtwccs_is_multiple_allowed', 0)) {
            add_action('the_post', array($this, 'the_post'), 1);
            add_action('load-post.php', array($this, 'admin_action_post'), 1);
        }


        add_action('nbtwccs_update_rates_wpcron', array($this, 'rate_auto_update'), 10);
        $this->cron = new PN_WP_CRON_NBTWCCS('nbtwccs_rates_wpcron');
        $this->wp_cron_period = (int) $this->get_nbtwccs_cron_schedules($this->rate_auto_update);
        $this->make_rates_auto_update();

        if ($this->is_fixed_enabled OR $this->is_geoip_manipulation) {
            $this->fixed = new NBTWCCS_FIXED_PRICE();
        }
        if ($this->is_fixed_coupon) {
            $this->fixed_coupon = new NBTWCCS_FIXED_COUPON();
        }
        if ($this->is_fixed_shipping) {
            $this->fixed_shipping = new NBTWCCS_FIXED_SHIPPING();
            $this->fixed_shipping_free = new NBTWCCS_FIXED_SHIPPING_FREE();
        }

        //for  any notises
        add_action('init', array($this, 'init_style_notice')); //add notice to cleare cache
        //adapt_filter
        add_filter('nbtwccs_convert_price', array($this, 'nbtwccs_convert_price'), 10, 2);
        add_filter('nbtwccs_back_convert_price', array($this, 'nbtwccs_back_convert_price'), 10, 2);
        add_filter('nbtwccs_convert_price_wcdp', array($this, 'nbtwccs_convert_price_wcdp'), 10, 3);
    }

//for normal shippng update if to change currency
    public function woocommerce_add_to_cart_hash($hash) {
        return md5(json_encode(WC()->cart->get_cart_for_session()) . $this->current_currency);
    }

    public function init() {
        
        if (!class_exists('WooCommerce')) {
            return;
        }
        wp_enqueue_script('jquery');
        add_filter('woocommerce_currency_symbol', array($this, 'woocommerce_currency_symbol'), 9999);
//if we use GeoLocation
        if (is_admin() AND ! is_ajax()) {
            $this->current_currency = $this->default_currency;
        } else {
//if we are in the a product backend and loading its variations
            if (is_ajax() AND ( isset($_REQUEST['action']) AND $_REQUEST['action'] == 'woocommerce_load_variations')) {
                $this->current_currency = $this->default_currency;
            }
        }

        if (is_ajax()) {
            $actions = false;
//code for manual order adding
            if (isset($_REQUEST['action']) AND $_REQUEST['action'] == 'woocommerce_add_order_item') {
                $actions = true;
            }

            if (isset($_REQUEST['action']) AND $_REQUEST['action'] == 'woocommerce_save_order_items') {
                $actions = true;
            }

            if (isset($_REQUEST['action']) AND $_REQUEST['action'] == 'woocommerce_calc_line_taxes') {
                $actions = true;
            }

            if ($actions AND current_user_can('edit_shop_orders')) {
                $this->current_currency = $this->default_currency;
//check if is order has installed currency
                $currency = get_post_meta($_REQUEST['order_id'], '_order_currency', TRUE);
                if (!empty($currency)) {
                    $this->current_currency = $currency;
                }
            }
        }

        if (is_ajax() AND isset($_REQUEST['action'])
                AND $_REQUEST['action'] == 'woocommerce_mark_order_status'
                AND isset($_REQUEST['status']) AND $_REQUEST['status'] == 'completed'
                AND isset($_REQUEST['order_id'])
        ) {
            $currency = get_post_meta($_REQUEST['order_id'], '_order_currency', true);
            if (!empty($currency)) {
                $_REQUEST['nbtwccs_in_order_currency'] = $currency;
                $this->current_currency = $currency;
            }
        }
//if we want to be paid in the basic currency - not multiple mode
        if (!get_option('nbtwccs_is_multiple_allowed', 0)) {


//compatibility for WC_Gateway_PayPal_Express_AngellEYE
            if (isset($_GET['wc-api']) AND isset($_GET['pp_action']) AND isset($_GET['use_paypal_credit'])) {
                if ($_GET['pp_action'] == 'expresscheckout') {
                    $this->reset_currency();
                }
            }
        }


        if ($this->force_pay_bygeoip_rules) {
            if ((is_checkout() OR is_checkout_pay_page()) AND ! isset($_GET['key'])) {
                $this->force_pay_bygeoip_rules();
            }            
        }

//Show Approx. data info
        if ($this->is_use_geo_rules() AND get_option('nbtwccs_show_approximate_amount', 0) AND ( isset(WC()->cart)/* AND WC()->cart->subtotal > 0 */)) {

            add_filter('woocommerce_cart_total', array($this, 'woocommerce_cart_total'), 9999, 1);

            add_filter('woocommerce_cart_item_price', array($this, 'woocommerce_cart_item_price'), 9999, 3);
            add_filter('woocommerce_cart_item_subtotal', array($this, 'woocommerce_cart_item_subtotal'), 9999, 3);
            add_filter('woocommerce_cart_subtotal', array($this, 'woocommerce_cart_subtotal'), 9999, 3);

            add_filter('woocommerce_cart_totals_taxes_total_html', array($this, 'woocommerce_cart_totals_taxes_total_html'), 9999, 1);
            add_filter('woocommerce_cart_tax_totals', array($this, 'woocommerce_cart_tax_totals'), 9999, 2);
            add_filter('woocommerce_cart_shipping_method_full_label', array($this, 'woocommerce_cart_shipping_method_full_label'), 9999, 2);
        }
        if (apply_filters('nbtwccs_cut_cart_price_format', true)) {
            add_action('woocommerce_cart_item_price', array($this, 'nbtwccs_woocommerce_cart_price_html'), 99999, 2);
            add_filter('woocommerce_cart_item_subtotal', array($this, 'nbtwccs_woocommerce_cart_price_html'), 99999, 2);
            add_filter('woocommerce_cart_subtotal', array($this, 'nbtwccs_woocommerce_cart_price_html'), 99999, 2);
            add_filter('woocommerce_cart_total', array($this, 'nbtwccs_woocommerce_cart_price_html'), 99999, 2);
        }

        //woo version control for enabling right functionality after migration from woo 2.6.x to 3.x.x
        
        if ($this->actualized_for !== floatval(WOOCOMMERCE_VERSION)) {
            update_option('nbtwccs_woo_version', WOOCOMMERCE_VERSION);
        }
    }

    public function make_rates_auto_update($reset = false) {
        if ($this->rate_auto_update != 'no' AND ! empty($this->rate_auto_update)) {
            if ($this->wp_cron_period) {
                if ($reset) {
                    $this->cron->reset($this->cron_hook, $this->wp_cron_period);
                }

                $this->nbtwccs_wpcron_init();
            }
        }
    }

    public function nbtwccs_wpcron_init($remove = false) {
        if ($remove) {
            $this->cron->remove($this->cron_hook);
            return;
        }

        if ($this->wp_cron_period) {
            if (!$this->cron->is_attached($this->cron_hook, $this->wp_cron_period)) {
                $this->cron->attach($this->cron_hook, time(), $this->wp_cron_period);
            }

            $this->cron->process();
        }
    }

    public function get_nbtwccs_cron_schedules($key = '') {
        $schedules = array(
            'min15' => 15 * MINUTE_IN_SECONDS,
            'min30' => 30 * MINUTE_IN_SECONDS,
            'min45' => 45 * MINUTE_IN_SECONDS,
            'hourly' => HOUR_IN_SECONDS,
            'twicedaily' => HOUR_IN_SECONDS * 12,
            'daily' => DAY_IN_SECONDS,
            'week' => WEEK_IN_SECONDS,
            'month' => WEEK_IN_SECONDS * 4,
            'min1' => MINUTE_IN_SECONDS,
        );
        if (!empty($key) AND isset($schedules[$key])) {
            return (int) $schedules[$key];
        } else {
            return NULL;
        }

        return $schedules;
    }

    public function get_currency_price_num_decimals($currency, $val = 2) {
        $currencies = $this->get_currencies();
        if (isset($currencies[$currency]['decimals'])) {
            $val = $currencies[$currency]['decimals'];
        }
        return intval($val);
    }

    public function woocommerce_price_num_decimals($default) {
        $this->price_num_decimals = $this->get_currency_price_num_decimals($this->current_currency);

        return $this->price_num_decimals;
    }

    public function body_class($classes) {
        $classes[] = 'currency-' . strtolower($this->current_currency);
        return $classes;
    }

    public function init_currency_symbols() {
        $this->currency_symbols = array_values($this->get_symbols_set());
        $this->currency_symbols['------'] = '--------'; //just divider

        $this->currency_symbols = apply_filters('nbtwccs_currency_symbols', array_merge($this->currency_symbols, $this->get_customer_signs()));
    }    

//for auto rate update sheduler
    public function rate_auto_update() {
        $currencies = $this->get_currencies();

        $_REQUEST['no_ajax'] = TRUE;
        $request = array();
        foreach ($currencies as $key => $currency) {
            if ($currency['is_etalon'] == 1) {
                continue;
            }
            $_REQUEST['currency_name'] = $currency['name'];
            $request[$key] = (float) $this->get_rate();
        }
//*** checking and assigning data
        foreach ($currencies as $key => $currency) {
            if ($currency['is_etalon'] == 1) {
                continue;
            }
            if (isset($request[$key]) AND ! empty($request[$key]) AND $request[$key] > 0) {
                $currencies[$key]['rate'] = $request[$key];
            }
        }
        
        static $email_is_sent = false;
        if (isset($_REQUEST['nbtwccs_cron_running']) AND ! $email_is_sent) {
            /*if (get_option('nbtwccs_rate_auto_update_email', 0)) {
                $message = sprintf(__('<strong>Base currency of the site is: %s</strong>', 'netbase_solutions'), $this->default_currency);
                $message .= '<br /><br /><ul>';
                foreach ($currencies as $code => $curr) {
                    if ($code == $this->default_currency) {
                        continue;
                    }

                    $message .= '<li><b>' . $code . '</b>: <i>' . $curr['rate'] . '</i><br /><br /></li>';
                }
                $message .= '</ul>';
                
                $headers = 'MIME-Version: 1.0' . "\r\n";
                $headers .= 'Content-type: text/html; charset=utf-8' . "\r\n";
                mail(get_bloginfo('admin_email'), 'Currency rates updated on ' . get_bloginfo('name'), $message, $headers);
            }*/

            $email_is_sent = true;
        }

        update_option('nbtwccs', $currencies);
    }

    public function init_geo_currency() {
        $done = false;
        if (!class_exists('WC_Geolocation')) {
            return false;
        }
        $pd = WC_Geolocation::geolocate_ip();
        $this->storage->set_val('nbtwccs_user_country', $pd['country']);
        
        if ($this->is_use_geo_rules()) {
            $rules = $this->get_geo_rules();
            if (apply_filters("nbtwccs_geobone_ip", false)) {
                if (intval($this->storage->get_val('nbtwccs_first_unique_geoip')) === 0) {
                    $this->is_first_unique_visit = true;
                    $this->storage->set_val('nbtwccs_first_unique_geoip', 1);
                }
            }
            $is_allowed = $this->is_first_unique_visit AND function_exists('wc_clean') AND function_exists('wp_validate_redirect');
            if ($is_allowed) {

                if (isset($pd['country']) AND ! empty($pd['country'])) {

                    if (!empty($rules)) {
                        foreach ($rules as $curr => $countries) {
                            if (!empty($countries) AND is_array($countries)) {
                                foreach ($countries as $country) {
                                    if ($country == $pd['country']) {
                                        $this->set_currency($curr);
                                        $done = true;
                                        break(2);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }        

        return $done;
    }

    public function get_currency_by_country($country_code) {
        $rules = $this->get_geo_rules();
        if (!empty($rules)) {
            foreach ($rules as $currency => $countries) {
                if (!empty($countries) AND is_array($countries)) {
                    foreach ($countries as $country) {
                        if ($country == $country_code) {
                            return $currency;
                        }
                    }
                }
            }
        }

        return '';
    }


    public function admin_enqueue_scripts() {        
        wp_enqueue_style('woocommerce-currency-switcher-options', NBTWCCS_LINK . 'assets/css/options.css');
        
    }

    public function admin_head() {
        if (isset($_GET['nbtwccs_reset'])) {
            delete_option('nbtwccs');
        }
    
        wp_enqueue_script('nbtwccs-admin', NBTWCCS_LINK . 'assets/js/admin.js', array('jquery'));
        
    }

    public function admin_footer() {
        global $post_type;

        if ('shop_order' == $post_type) {
            ?>
            <script type="text/javascript">
                jQuery(function () {
                    jQuery('<option>').val('nbtwccs_convert_to_default').text('<?php _e('NBTWCCS - recalculate orders', 'netbase_solutions') ?>').appendTo('select[name="action"]');
                    jQuery('<option>').val('nbtwccs_convert_to_default').text('<?php _e('NBTWCCS - recalculate orders', 'netbase_solutions') ?>').appendTo('select[name="action2"]');
                });
            </script>
            <?php
        }
    }

    /**
     * Process the new bulk actions for changing order currency to default.
     */
    public function shop_order_bulk_actions() {
        $wp_list_table = _get_list_table('WP_Posts_List_Table');
        $action = $wp_list_table->current_action();        
    }

    public function admin_init() {
        if (get_option('nbtwccs_is_multiple_allowed', 0)) {
            add_meta_box('nbtwccs_order_metabox', __('NBTWCCS Order Info', 'netbase_solutions'), array($this, 'nbtwccs_order_metabox'), 'shop_order', 'side', 'default');
        }
        add_meta_box( 'add-wc-currency-switcher-section', __( 'WC Currency Switcher', 'netbase_solutions' ), array( $this, 'nav_currency_meta_box' ), 'nav-menus', 'side', 'default' );
    }

    public function nbt_start_el($item_output, $item){
        
        if ( !empty($item->object) && 'navcurrency' == $item->object ) {                  
            $item_output = do_shortcode( '[nbt_currency_switcher]' );
        }       
        return $item_output;
    }

    public function nav_currency_meta_box() {                      
    ?>
            <div id="posttype-navcurrency" class="posttypediv">
                <div id="tabs-panel-currency-login" class="tabs-panel tabs-panel-active">
                    <ul id ="currency-checklist" class="categorychecklist form-no-clear">
                        <li>
                            <label class="menu-item-title">
                                <input type="checkbox" class="menu-item-checkbox" name="menu-item[-1][menu-item-object-id]" value="-1"> Currency Switcher 
                            </label>
                            <input type="hidden" class="menu-item-type" name="menu-item[-1][menu-item-type]" value="navcurrency">
                            <input type="hidden" class="menu-item-title" name="menu-item[-1][menu-item-title]" value="Currency Switcher">
                            <input type="hidden" class="menu-item-url" name="menu-item[-1][menu-item-url]" value="">
                            <input type="hidden" class="menu-item-object" name="menu-item[-1][menu-item-object]" value="navcurrency" />
                            <input type="hidden" class="menu-item-classes" name="menu-item[-1][menu-item-classes]" value="nav-currency-dropdown">
                        </li>
                    </ul>
                </div>
                <p class="button-controls">                    
                    <span class="add-to-menu">
                        <input type="submit" class="button-secondary submit-add-to-menu right" value="Add to Menu" name="add-post-type-menu-item" id="submit-posttype-navcurrency">
                        <span class="spinner"></span>
                    </span>
                </p>
            </div>
            <?php
    }

//for orders hook
    public function save_post($order_id) {
        if (current_user_can('edit_shop_orders')) {
            if (!empty($_POST)) {
                global $post;
                if (is_object($post)) {
                    if (($post->post_type == 'shop_order' || $post->post_type == 'shop_subscription') AND isset($_POST['nbtwccs_order_currency'])) {
                        $currencies = $this->get_currencies();
                        $currencies_keys = array_keys($currencies);
                        $currency = $this->escape($_POST['nbtwccs_order_currency']);
                        if (in_array($currency, $currencies_keys)) {

//changing order currency
                            update_post_meta($order_id, '_order_currency', $currency);

                            update_post_meta($order_id, '_nbtwccs_order_rate', $currencies[$currency]['rate']);
                            wc_add_order_item_meta($order_id, '_nbtwccs_order_rate', $currencies[$currency]['rate'], true);

                            update_post_meta($order_id, '_nbtwccs_order_base_currency', $this->default_currency);
                            wc_add_order_item_meta($order_id, '_nbtwccs_order_base_currency', $this->default_currency, true);

                            update_post_meta($order_id, '_nbtwccs_order_currency_changed_mannualy', time());
                            wc_add_order_item_meta($order_id, '_nbtwccs_order_currency_changed_mannualy', time(), true);
                        }
                    }
                }
            }
        }
    }

//for orders hook
    public function the_post($post) {
        if (is_object($post) AND $post->post_type == 'shop_order') {
            $currency = get_post_meta($post->ID, '_order_currency', true);
            if (!empty($currency)) {
                $_REQUEST['nbtwccs_in_order_currency'] = $currency;
                $this->current_currency = $currency;
            }
        }

        return $post;
    }

//for orders hook
    public function admin_action_post() {
        if (isset($_GET['post'])) {
            $post_id = $_GET['post'];
            $post = get_post($post_id);
            if (is_object($post) AND $post->post_type == 'shop_order') {
                $currency = get_post_meta($post->ID, '_order_currency', true);
                if (!empty($currency)) {
                    $_REQUEST['nbtwccs_in_order_currency'] = $currency;
                    $this->current_currency = $currency;
                }
            }
        }
    }

    public function nbtwccs_order_metabox($post) {
        $data = array();
        $data['post'] = $post;
        $data['order'] = new WC_Order($post->ID);
        echo $this->render_html(NBTWCCS_PATH . 'tpl/nbtwccs_order_metabox.php', $data);
    }

    public function wp_head() {
        if (!class_exists('WooCommerce')) {
            return;
        }
//*** if the site is visited for the first time lets execute geo ip conditions
        $this->init_geo_currency();
        wp_enqueue_script('jquery');
        wp_enqueue_script('wc-price-slider_33');
        $currencies = $this->get_currencies();
        ?>
        <script type="text/javascript">
            var nbtwccs_is_mobile = <?php echo (int) wp_is_mobile() ?>;
            var nbtwccs_drop_down_view = "<?php echo $this->get_drop_down_view(); ?>";
            var nbtwccs_current_currency = <?php echo json_encode((isset($currencies[$this->current_currency]) ? $currencies[$this->current_currency] : $currencies[$this->default_currency])) ?>;
            var nbtwccs_default_currency = <?php echo json_encode($currencies[$this->default_currency]) ?>;
            var nbtwccs_array_of_get = '{}';
            <?php if (!empty($_GET)): 

            $sanitized_get_array = array();
            foreach ($_GET as $key => $value) {
                $sanitized_get_array[$this->escape($key)] = $this->escape($value);
            }
            ?>
            nbtwccs_array_of_get = '<?php echo str_replace("'", "", json_encode($sanitized_get_array)); ?>';
            <?php endif; ?>

            nbtwccs_array_no_cents = '<?php echo json_encode($this->no_cents); ?>';
            var nbtwccs_ajaxurl = "<?php echo admin_url('admin-ajax.php'); ?>";
            var nbtwccs_lang_loading = "<?php _e('loading', 'netbase_solutions') ?>";
            var nbtwccs_shop_is_cached =<?php echo (int) $this->shop_is_cached ?>;
        </script>
        <?php
        wp_enqueue_style('woocommerce-currency-switcher', NBTWCCS_LINK . 'assets/css/front.css');
        wp_enqueue_script('woocommerce-currency-switcher', NBTWCCS_LINK . 'assets/js/front.js', array('jquery'));

        if (isset($_GET['pay_for_order']) AND is_checkout_pay_page()) {
            if ($_GET['pay_for_order'] == 'true' AND isset($_GET['key'])) {
                $order_id = wc_get_order_id_by_order_key($_GET['key']);
                $currency = get_post_meta($order_id, '_order_currency', TRUE);
                $this->set_currency($currency);
            }
        }


//if we want to be paid in the basic currency - not multiple mode and in is_geoip_manipulation
        if (!get_option('nbtwccs_is_multiple_allowed', 0)) {
            if (is_checkout() OR is_checkout_pay_page()) {
                $this->reset_currency();
            }
        }

        //logic hack for some cases when shipping for example is wrong in
        //non multiple mode but customer doesn work allow pay in user selected currency
        if ($this->is_multiple_allowed) {
            if ((is_checkout() OR is_checkout_pay_page()) AND $this->bones['reset_in_multiple']) {
                $this->reset_currency();
            }
        }

        if ($this->force_pay_bygeoip_rules) {
            if ((is_checkout() OR is_checkout_pay_page()) AND ! isset($_GET['key'])) {
                $this->force_pay_bygeoip_rules();
            }
        }
    }

    public function woocommerce_checkout_update_order_review() {
        if (!get_option('nbtwccs_is_multiple_allowed', 0)) {
            $this->reset_currency();
        }
        $this->force_pay_bygeoip_rules();
    }

    public function woocommerce_settings_tabs_array($tabs) {
        $tabs['nbtwccs'] = __('Currency', 'netbase_solutions');
        return $tabs;
    }


    public function register_subpage_media1() {
        if( defined('PREFIX_NBT_SOL') && defined('PREFIX_NBT_SOL_DEV') && PREFIX_NBT_SOL_DEV ) {
            add_submenu_page('solutions', 'Currency Switcher', 'Currency Switcher', 'manage_options', 'wc-currency-switcher', array($this, 'print_plugin_options')); 
        }else{
            add_submenu_page('solution-dashboard', 'Currency Switcher', 'Currency Switcher', 'manage_options', 'wc-currency-switcher', array($this, 'print_plugin_options')); 
        }       

    }

    public function print_plugin_options() {
        if (isset($_POST['nbtwccs_name']) AND ! empty($_POST['nbtwccs_name'])) {
            $result = array();
            update_option('nbtwccs_drop_down_view', $this->escape($_POST['nbtwccs_drop_down_view']));
            update_option('nbtwccs_currencies_aggregator', $this->escape($_POST['nbtwccs_currencies_aggregator']));
            update_option('nbtwccs_welcome_currency', $this->escape($_POST['nbtwccs_welcome_currency']));
            update_option('nbtwccs_is_multiple_allowed', (int) $_POST['nbtwccs_is_multiple_allowed']);
/*            update_option('nbtwccs_is_geoip_manipulation', (int) $_POST['nbtwccs_is_geoip_manipulation']);*/
            if ((int) $_POST['nbtwccs_is_multiple_allowed']) {
/*                update_option('nbtwccs_is_fixed_enabled', (int) $_POST['nbtwccs_is_fixed_enabled']);
                update_option('nbtwccs_is_fixed_coupon', (int) $_POST['nbtwccs_is_fixed_coupon']);
                update_option('nbtwccs_is_fixed_shipping', (int) $_POST['nbtwccs_is_fixed_shipping']);
                if ((int) $_POST['nbtwccs_is_fixed_enabled']) {
                    update_option('nbtwccs_force_pay_bygeoip_rules', (int) $_POST['nbtwccs_force_pay_bygeoip_rules']);
                } else {
                    update_option('nbtwccs_force_pay_bygeoip_rules', 0);
                }*/
            } else {
                /*update_option('nbtwccs_is_fixed_enabled', 0);
                update_option('nbtwccs_is_fixed_coupon', 0);
                update_option('nbtwccs_is_fixed_shipping', 0);
                update_option('nbtwccs_force_pay_bygeoip_rules', 0);*/
            }
/*            update_option('nbtwccs_customer_signs', $this->escape($_POST['nbtwccs_customer_signs']));*/
/*            update_option('nbtwccs_customer_price_format', $this->escape($_POST['nbtwccs_customer_price_format']));*/
            update_option('nbtwccs_currencies_rate_auto_update', $this->escape($_POST['nbtwccs_currencies_rate_auto_update']));

            /*update_option('nbtwccs_show_flags', (int) $_POST['nbtwccs_show_flags']);*/
            update_option('nbtwccs_show_money_signs', (int) $_POST['nbtwccs_show_money_signs']);
            update_option('nbtwccs_storage', $this->escape($_POST['nbtwccs_storage']));
            if (isset($_POST['nbtwccs_geo_rules'])) {
                $nbtwccs_geo_rules = array();
                if (!empty($_POST['nbtwccs_geo_rules'])) {
                    foreach ($_POST['nbtwccs_geo_rules'] as $curr_key => $countries) {
                        $nbtwccs_geo_rules[$this->escape($curr_key)] = array();
                        if (!empty($countries)) {
                            foreach ($countries as $curr) {
                                $nbtwccs_geo_rules[$this->escape($curr_key)][] = $this->escape($curr);
                            }
                        }
                    }
                }
                update_option('nbtwccs_geo_rules', $nbtwccs_geo_rules);
            } else {
                update_option('nbtwccs_geo_rules', '');
            }            
            update_option('nbtwccs_hide_cents', (int) $_POST['nbtwccs_hide_cents']);
/*            update_option('nbtwccs_price_info', (int) $_POST['nbtwccs_price_info']);*/
/*            update_option('nbtwccs_no_cents', $this->escape($_POST['nbtwccs_no_cents']));*/
            update_option('nbtwccs_restrike_on_checkout_page', (int) $_POST['nbtwccs_restrike_on_checkout_page']);
/*            update_option('nbtwccs_show_approximate_amount', (int) $_POST['nbtwccs_show_approximate_amount']);*/
            update_option('nbtwccs_shop_is_cached', (int) $_POST['nbtwccs_shop_is_cached']);
            update_option('nbtwccs_woo_version', WOOCOMMERCE_VERSION);

            $cc = '';
            foreach ($_POST['nbtwccs_name'] as $key => $name) {
                if (!empty($name)) {
                    $symbol = $this->escape($_POST['nbtwccs_symbol'][$key]); //md5 encoded

                    foreach ($this->currency_symbols as $s) {
                        if (md5($s) == $symbol) {
                            $symbol = $s;
                            break;
                        }
                    }

                    $result[strtoupper($name)] = array(
                        'name' => $name,
                        'rate' => floatval($_POST['nbtwccs_rate'][$key]),
                        'symbol' => $symbol,
                        'position' => (in_array($this->escape($_POST['nbtwccs_position'][$key]), $this->currency_positions) ? $this->escape($_POST['nbtwccs_position'][$key]) : $this->currency_positions[0]),
                        'is_etalon' => (int) $_POST['nbtwccs_is_etalon'][$key],
                        'hide_cents' => (int) @$_POST['nbtwccs_hide_cents'][$key],
                        'decimals' => (int) @$_POST['nbtwccs_decimals'][$key],
                        'description' => $this->escape($_POST['nbtwccs_description'][$key]),
                        'flag' => $this->escape($_POST['nbtwccs_flag'][$key]),
                    );

                    if ($_POST['nbtwccs_rate'][$key] == 1) {
                        $cc = $name;
                    }
                }
            }

            update_option('nbtwccs', $result);
            if (!empty($cc)) {
//set default currency for all woocommerce system
                update_option('woocommerce_currency', $cc);
            }
            $this->init_currency_symbols();

            $this->rate_auto_update = $this->escape($_POST['nbtwccs_currencies_rate_auto_update']);
            $this->wp_cron_period = $this->get_nbtwccs_cron_schedules($this->rate_auto_update);
            $this->nbtwccs_wpcron_init(true);
            $this->make_rates_auto_update(true);

        }

        wp_enqueue_script('media-upload');
        wp_enqueue_style('thickbox');
        wp_enqueue_script('thickbox');
        wp_enqueue_script('jquery');
        wp_enqueue_script('jquery-ui-core');
        
        wp_enqueue_script('woocommerce-currency-switcher-options', NBTWCCS_LINK . 'assets/js/options.js', array('jquery', 'jquery-ui-core', 'jquery-ui-sortable'));

        $args = array();
        $args['currencies'] = $this->get_currencies();
        if ($this->is_use_geo_rules()) {
            $args['geo_rules'] = $this->get_geo_rules();
        }
        ?>
        <form id="frm-wc-currency-switcher" action="" method="post" >
        <?php
        echo $this->render_html(NBTWCCS_PATH . 'tpl/plugin_options.php', $args);
        ?>
        <div class="submit">
            <?php wp_nonce_field( 'solution-settings' ) ?>
            <input type="submit" name="submit-wc-currency-switcher" value="<?php _e('Save Changes', 'nbt-solution-core') ?>" class="button-primary" />
        </div>
        </form>
        <?php
    }

    public function get_drop_down_view() {
        return apply_filters('nbtwccs_drop_down_view', get_option('nbtwccs_drop_down_view', 'no'));

    }

    public function get_currencies() {

        $currencies = get_option('nbtwccs', array());

        if (empty($currencies) OR ! is_array($currencies) OR count($currencies) < 2) {
            $currencies = $this->prepare_default_currencies();
        }
        $currencies = apply_filters('nbtwccs_currency_data_manipulation', $currencies);
        return $currencies;
    }

    public function get_geo_rules() {
        return get_option('nbtwccs_geo_rules', array());
    }

    public function is_use_geo_rules() {
        
        $is = true; //from v.2.1.8 always enabled
        $isset = class_exists('WC_Geolocation');

        return ($is && $isset);
    }

//need for paypal currencies supporting
    public function enable_custom_currency($currency_array) {
//https://developer.paypal.com/docs/classic/api/currency_codes/
//includes\gateways\paypal\class-wc-gateway-paypal.php => woo func
//function is_valid_for_use() =>Check if this gateway is enabled and available in the user's country
        $currency_array[] = 'usd';
        $currency_array[] = 'aud';
        $currency_array[] = 'brl';
        $currency_array[] = 'cad';
        $currency_array[] = 'czk';
        $currency_array[] = 'dkk';
        $currency_array[] = 'eur';
        $currency_array[] = 'hkd';
        $currency_array[] = 'huf';
        $currency_array[] = 'ils';
        $currency_array[] = 'jpy';
        $currency_array[] = 'myr';
        $currency_array[] = 'mxn';
        $currency_array[] = 'nok';
        $currency_array[] = 'nzd';
        $currency_array[] = 'php';
        $currency_array[] = 'pln';
        $currency_array[] = 'gbp';
        $currency_array[] = 'rub';
        $currency_array[] = 'sgd';
        $currency_array[] = 'sek';
        $currency_array[] = 'chf';
        $currency_array[] = 'twd';
        $currency_array[] = 'thb';
        $currency_array[] = 'try';
        $currency_array = array_map('strtoupper', $currency_array);
        return $currency_array;
    }

    public function woocommerce_currency_symbol($currency_symbol) {
        if (is_order_received_page() || is_account_page()) {
            return $currency_symbol;
        }
        $currencies = $this->get_currencies();

        if (!isset($currencies[$this->current_currency])) {
            $this->reset_currency();
        }

        return $currencies[$this->current_currency]['symbol'];
    }

    public function get_woocommerce_currency() {
        return $this->current_currency;
    }

    //work in for multiple mode only from woocommerce 2.4
    //wp-content\plugins\woocommerce\includes\class-wc-product-variable.php #303
    public function woocommerce_variation_prices($prices_array) {
        $current_currency = $this->current_currency;       

        if (in_array($current_currency, $this->no_cents)/* OR $currencies[$this->current_currency]['hide_cents'] == 1 */) {
            $precision = 0;
        } else {
            if ($current_currency != $this->default_currency) {
                $precision = $this->get_currency_price_num_decimals($current_currency, $this->price_num_decimals);
            } else {
                $precision = $this->get_currency_price_num_decimals($this->default_currency, $this->price_num_decimals);
            }
        }

        if (!empty($prices_array) AND is_array($prices_array)) {
            //remove sale prices if they equal to regular prices
            foreach ($prices_array['regular_price'] as $key => $value) {
                if ($value === $prices_array['sale_price'][$key]) {
                    //unset($prices_array['sale_price'][$key]);
                }
            }

            
            foreach ($prices_array as $key => $values) {
                if (!empty($values)) {
                    foreach ($values as $product_id => $price) {

                        $type = 'regular';
                        if ($key === 'sale_price') {//OR $key === 'price') {
                            $type = 'sale';
                        }

                        $is_price_custom = false;

                        if ($this->is_fixed_enabled AND $this->fixed->is_exists($product_id, $current_currency, $type)) {
                            $tmp = number_format(floatval($this->fixed->get_value($product_id, $current_currency, $type)), $precision, $this->decimal_sep, '');

                            if ((int) $tmp !== -1) {
                                if (wc_tax_enabled()) {
                                    $tmp = $this->nbtwccs_calc_tax_price(wc_get_product($product_id), $tmp);
                                }
                                $prices_array[$key][$product_id] = $tmp;
                                $is_price_custom = true;
                                if ($type == 'sale') {
                                    $prices_array['price'][$product_id] = $tmp;
                                }
                            }
                        }

                        if ($this->is_geoip_manipulation AND ! $is_price_custom) {
                            $product = (object) array('id' => $product_id);
                            $price = $this->_get_product_geo_price($product, $price);
                        }
                        if (!$is_price_custom) {
                            $prices_array[$key][$product_id] = apply_filters('nbtwccs_woocommerce_variation_prices', number_format(floatval($this->nbtwccs_exchange_value(floatval($price))), $precision, $this->decimal_sep, ''));
                            
                        }
                    }
                }
            }
        }
        
        //*** lets sort arrays by values to avoid wrong price displaying on the front
        if (!empty($prices_array) AND is_array($prices_array)) {
            foreach ($prices_array as $key => $arrvals) {
                asort($arrvals);
                $prices_array[$key] = $arrvals;
            }
        }
        
        //another way displaing of price range is not correct
        if (empty($prices_array['sale_price'])) {
            if (isset($prices_array['regular_price'])) {
                $prices_array['price'] = $prices_array['regular_price'];
            }
        }
        
        return $prices_array;
    }

    public function woocommerce_variation_prices_regular($price, $variant, $product) {
        return $price;
    }

    public function woocommerce_variation_prices_sale($price, $variant, $product) {
        return $price;
    }

    public function woocommerce_variation_prices_fix_3_3($price, $product_id, $type) { //fix 3.3.3
        $is_empty = $this->fixed->is_empty($product_id, $this->current_currency, $type);
        $is_exists = $this->fixed->is_exists($product_id, $this->current_currency, $type);

        if ($is_exists AND ! $is_empty) {
            return floatval($this->fixed->get_value($product_id, $this->current_currency, $type));
        }

        return $price;
    }

    public function woocommerce_get_variation_prices_hash($price_hash, $product, $display) {        
        return "";
    }

    
    public function raw_woocommerce_price($price, $product = NULL) {

        if (isset($_REQUEST['nbtwccs_block_price_hook'])) {
            return $price;
        }

        //to avoid 'Free!' text if price is zero - buy button will be hidden
        if (empty($price)) {
            //return "";//doesn work correctly for the fixed prices
        }        

        $currencies = $this->get_currencies();
        if (in_array($this->current_currency, $this->no_cents)/* OR $currencies[$this->current_currency]['hide_cents'] == 1 */) {
            $precision = 0;
        } else {
            if ($this->current_currency != $this->default_currency) {
                $precision = $this->get_currency_price_num_decimals($this->current_currency, $this->price_num_decimals);
            } else {
                $precision = $this->get_currency_price_num_decimals($this->default_currency, $this->price_num_decimals);
            }
        }


        $is_price_custom = false;
        if ($this->is_fixed_enabled) {
            if ($this->is_multiple_allowed AND $product !== NULL AND is_object($product)) {                
                if ($product->is_type('variation')) {
                    $tmp_val = $this->_get_product_fixed_price($product, 'variation', $price, $precision);
                } else {
                    $tmp_val = $this->_get_product_fixed_price($product, 'single', $price, $precision);
                }

                if ((int) $tmp_val !== -1) {
                    $price = apply_filters('nbtwccs_fixed_raw_woocommerce_price', $tmp_val, $product, $price);
                    $is_price_custom = true;
                }

            }
        }
        
        if ($this->is_geoip_manipulation AND ! $is_price_custom) {
            if ($product !== NULL) {
                try {
                    $product_emulator = (object) array('id' => $product->get_id());
                } catch (Exception $e) {
                    //print_r($e);
                }

                $price = $this->_get_product_geo_price($product_emulator, $price);
            }
        }        

        if (!$is_price_custom) {
            if ($this->current_currency != $this->default_currency) {
                //Edited this line to set default convertion of currency
                if (isset($currencies[$this->current_currency]) AND $currencies[$this->current_currency] != NULL) {
                    $price = number_format(floatval((float) $price * (float) $currencies[$this->current_currency]['rate']), $precision, $this->decimal_sep, '');
                } else {
                    $price = number_format(floatval((float) $price * (float) $currencies[$this->default_currency]['rate']), $precision, $this->decimal_sep, '');
                }
            }
        }


        return apply_filters('nbtwccs_raw_woocommerce_price', $price);

    }

    //fix for only woo>=2.7 when multiple mode is activated and price is not sale - price still crossed out
    public function raw_woocommerce_price_sale($price, $product = NULL) {

        if (!$this->is_multiple_allowed) {
            return $this->raw_woocommerce_price($price, $product);
        }

        if ($this->is_multiple_allowed) {
            if ($product !== NULL) {
                if ($product->get_sale_price('edit') > 0) {
                    return $this->raw_woocommerce_price($price, $product);
                }
            }
        }
    }

    //+++++++++++++++++++++++++++++ START: USES ONLY FOR WOO > 2.7 AS FIX ON THE CHEKOUT FOR VARIABLE PRODUCTS ++++++++++++++++++++++++++++++++
    //works only in multiple allowed mode
    public function woocommerce_cart_product_subtotal($product_subtotal, $product, $quantity, $cart) {

        if ($product->post_type == 'product_variation') {
            //$product_subtotal = $this->raw_woocommerce_price($product->get_price()*$quantity, $product);
            $product_subtotal = $this->wc_price($product->get_price() * $quantity);
        }

        return $product_subtotal;
    }

    public function woocommerce_cart_product_price($price, $product) {

        if ($product->post_type == 'product_variation') {
            $price = $this->wc_price($product->get_price());
        }

        return $price;
    }

    public function woocommerce_cart_subtotal2($cart_subtotal, $compound, $cart) {
        
        if (!empty($cart) AND isset($cart->cart_contents)) {
            if (!empty($cart->cart_contents)) {
                $cart_subtotal = 0;
                foreach ($cart->cart_contents as $ci) {
                    if ($ci['variation_id'] > 0) {
                        $cart_subtotal += $this->nbtwccs_exchange_value($ci['line_total']);
                    } else {
                        $cart_subtotal += $ci['line_total'];
                    }
                }
            }
        }

        return $this->wc_price($cart_subtotal, false);
    }

    public function woocommerce_cart_contents_total2($cart_contents_total) {
        return 101;
    }

    //+++++++++++++++++++++++++++++ FIINISH: USES ONLY FOR WOO > 2.7 AS FIX ON THE CHEKOUT FOR VARIABLE PRODUCTS ++++++++++++++++++++++++++++++++
    //for tooltip
    private function _get_min_max_variation_prices($product, $current_currency) {
        $currencies = $this->get_currencies();
        $prices_array = $product->get_variation_prices();
        $var_products_ids = array_keys($prices_array['regular_price']);
        $prices_array = array();
        if (!empty($var_products_ids)) {
            foreach ($var_products_ids as $var_prod_id) {

                $is_price_custom = false;
                $regular_price = (float) get_post_meta($var_prod_id, '_regular_price', true);
                $sale_price = (float) get_post_meta($var_prod_id, '_sale_price', true);                

                if ($this->is_fixed_enabled) {
                    $type = 'regular';
                    $fixed_regular_price = -1;
                    $fixed_sale_price = -1;

                    if ($this->fixed->is_exists($var_prod_id, $current_currency, $type)) {
                        $tmp = $this->fixed->get_value($var_prod_id, $current_currency, $type);
                        if ((int) $tmp !== -1) {
                            $fixed_regular_price = $tmp;
                        }
                    }

                    $type = 'sale';
                    if ($this->fixed->is_exists($var_prod_id, $current_currency, $type)) {
                        $tmp = $this->fixed->get_value($var_prod_id, $current_currency, $type);
                        if ((int) $tmp !== -1) {
                            $fixed_sale_price = $tmp;
                        }
                    }

                    if ((int) $fixed_sale_price !== -1) {
                        $prices_array[] = $fixed_sale_price;
                        $is_price_custom = true;
                    } else {
                        if ((int) $fixed_regular_price !== -1) {
                            $prices_array[] = $fixed_regular_price;
                            $is_price_custom = true;
                        }
                    }
                }

                if ($this->is_geoip_manipulation AND ! $is_price_custom) {
                    $product = (object) array('id' => $var_prod_id);
                    $regular_price = floatval($this->_get_product_geo_price($product, $regular_price));
                    $sale_price = floatval($this->_get_product_geo_price($product, $sale_price));
                    
                }

                if (!$is_price_custom) {
                    $regular_price = floatval($currencies[$current_currency]['rate'] * $regular_price);
                    $sale_price = floatval($currencies[$current_currency]['rate'] * $sale_price);

                    if ($sale_price > 0) {
                        $prices_array[] = $sale_price;
                    } else {
                        $prices_array[] = $regular_price;
                    }
                }
            }
        }

        if (!empty($prices_array)) {
            foreach ($prices_array as $key => $value) {
                if (floatval($value) <= 0) {
                    unset($prices_array[$key]);
                }
            }            
            if (!empty($prices_array)) {
                return array('min' => min($prices_array), 'max' => max($prices_array));
            }
        }

        return array();
    }    
    public function _get_product_fixed_price($product, $product_type, $price, $precision = 2, $type = NULL) {

        $product_id = $product->get_id();        
        if (!$type) {
            $type = $this->fixed->get_price_type($product, $price);
        }

        $is_empty = $this->fixed->is_empty($product_id, $this->current_currency, $type);
        $is_exists = $this->fixed->is_exists($product_id, $this->current_currency, $type);

        //if sale field is empty BUT regular not, in such case price exists and it is regular
        if ($type == 'sale' AND $is_empty) {
            $type = 'regular';
            $is_exists = $this->fixed->is_exists($product_id, $this->current_currency, $type);
            $is_empty = $this->fixed->is_empty($product_id, $this->current_currency, $type);
        }

        if ($is_exists AND ! $is_empty) {
            return number_format(floatval($this->fixed->get_value($product_id, $this->current_currency, $type)), $precision, $this->decimal_sep, '');
        }

        return -1;
    }

    private function _get_product_geo_price($product, $price, $type = NULL, $is_array = false) {
        $is_price_custom = false;
        if ($product !== NULL AND is_object($product)) {
            if (method_exists($product, 'get_id')) {
                $product_id = $product->get_id();
            } else {
                $product_id = $product->id;
            }

            if (!$type) {
                $type = $this->fixed->get_price_type($product, $price);
            }            

            $product_geo_data = $this->fixed->get_product_geo_data($product_id);

            if (isset($product_geo_data[$type . '_price_geo'])) {
                if (!empty($product_geo_data[$type . '_price_geo'])) {
                    $user_country = $this->storage->get_val('nbtwccs_user_country');
                    if (!empty($user_country)) {
                        if (!empty($product_geo_data['price_geo_countries'])) {
                            $price_key = '';
                            foreach ($product_geo_data['price_geo_countries'] as $block_key => $countries_codes) {
                                if (!empty($countries_codes)) {
                                    foreach ($countries_codes as $country_code) {
                                        if ($country_code === $user_country) {
                                            $price_key = $block_key;
                                            break(2);
                                        }
                                    }
                                }
                            }                            

                            if (isset($product_geo_data[$type . '_price_geo'][$price_key])) {
                                $price = $product_geo_data[$type . '_price_geo'][$price_key];
                                $is_price_custom = true;
                            }
                        }
                    }
                }
            }
        }

        if ($is_array) {
            return array($price, $is_price_custom);
        }

        return $price;
    }

    public function get_welcome_currency() {
        return get_option('nbtwccs_welcome_currency');
    }

    public function get_customer_signs() {
        $signs = array();
        /*$data = get_option('nbtwccs_customer_signs', '');
        if (!empty($data)) {
            $data = explode(',', $data);
            if (!empty($data) AND is_array($data)) {
                $signs = $data;
            }
        }*/
        return $signs;
    }

    public function get_checkout_page_id() {
        return (int) get_option('woocommerce_checkout_page_id');
    }

    public function force_pay_bygeoip_rules() {
        //$use_geo_rules = get_option('nbtwccs_use_geo_rules', 0);
        $use_geo_rules = true;
        if ($this->is_multiple_allowed AND $this->force_pay_bygeoip_rules AND $use_geo_rules) {
            $country = $this->storage->get_val('nbtwccs_user_country');
            $user_currency = $this->get_currency_by_country($country);
            if (!empty($user_currency)) {
                //$user_currency is empty its mean that current country is not in geo ip rules
                $this->set_currency($user_currency);
            }
            do_action('nbtwccs_force_pay_bygeoip_rules', $country, $user_currency, $this->current_currency);
        }
    }

    public function woocommerce_price_format() {
        $currencies = $this->get_currencies();
        $currency_pos = 'left';
        if (isset($currencies[$this->current_currency])) {
            $currency_pos = $currencies[$this->current_currency]['position'];
        }
        $format = '%1$s%2$s';
        switch ($currency_pos) {
            case 'left' :
                $format = '%1$s%2$s';
                break;
            case 'right' :
                $format = '%2$s%1$s';
                break;
            case 'left_space' :
                $format = '%1$s&nbsp;%2$s';
                break;
            case 'right_space' :
                $format = '%2$s&nbsp;%1$s';
                break;
        }

        return apply_filters('nbtwccs_price_format', $format, $currency_pos);
    }

//[nbtwccs]
    public function nbtwccs_shortcode($args) {
        if (empty($args)) {
            $args = array();
        }
        return $this->render_html(NBTWCCS_PATH . 'tpl/shortcodes/nbtwccs.php', $args);
    }

//[nbtwccs_converter exclude="GBP,AUD" precision=2]
    public function nbtwccs_converter($args) {
        if (empty($args)) {
            $args = array();
        }
        return $this->render_html(NBTWCCS_PATH . 'tpl/shortcodes/nbtwccs_converter.php', $args);
    }

//[nbtwccs_rates exclude="GBP,AUD" precision=2]
    public function nbtwccs_rates($args) {
        if (empty($args)) {
            $args = array();
        }
        return $this->render_html(NBTWCCS_PATH . 'tpl/shortcodes/nbtwccs_rates.php', $args);
    }

//[nbtwccs_show_current_currency text="" currency="" flag=1 code=1]
    public function nbtwccs_show_current_currency($atts) {
        $currencies = $this->get_currencies();
        extract(shortcode_atts(array(
            'text' => __('Current currency is:', 'netbase_solutions'),
            'currency' => $this->current_currency,
            'flag' => 1,
            'code' => 1,
                        ), $atts));

        $args = array();
        $args['currencies'] = $currencies;
        $args['text'] = $text;
        $args['currency'] = $currency;
        $args['flag'] = $flag;
        $args['code'] = $code;
        return $this->render_html(NBTWCCS_PATH . 'tpl/shortcodes/nbtwccs_show_current_currency.php', $args);
    }

//[nbtwccs_show_custom_price value=20] -> value should be in default currency
    public function nbtwccs_show_custom_price($atts) {
        extract(shortcode_atts(array('value' => 0), $atts));
        $currencies = $this->get_currencies();
        $convert = true;
        $_REQUEST['nbtwccs_show_custom_price'] = TRUE;
        $wc_price = $this->wc_price($value, $convert, array('currency' => $currencies[$this->current_currency]['name']));
        unset($_REQUEST['nbtwccs_show_custom_price']);
        return $wc_price;
    }

    //for geo ip demo
    public function nbtwccs_geo_hello($atts = '') {
        $pd = array();
        $countries = array();
        $text = '';
        if (class_exists('WC_Geolocation')) {
            $c = new WC_Countries();
            $countries = $c->get_countries();
            $pd = WC_Geolocation::geolocate_ip();
        }
        if (!empty($pd) AND ! empty($countries)) {
            $text = '<span style="color:green; font-size:18px; font-weight:normal; line-height:0;">' . sprintf(__('Your country is: <b>%s</b>. <br /><i style="color:black; font-size:11px; font-weight:normal;">(defined by woocommerce GeoIP functionality)</i>', 'netbase_solutions'), $countries[$pd['country']]) . '</span>';
        } else {
            $text = '<i style="color:red; font-size:18px; font-weight:normal;">' . __('Your country is not defined! Troubles with GeoIp service.', 'netbase_solutions') . '</i>';
        }

        return $text;
    }

//http://stackoverflow.com/questions/6918623/curlopt-followlocation-cannot-be-activated
    private function file_get_contents_curl($url) {
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_URL, $url);
        @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);

        $data = curl_exec($ch);
        curl_close($ch);

        return $data;
    }

//ajax
    public function get_rate() {
        $is_ajax = true;
        if (isset($_REQUEST['no_ajax'])) {
            $is_ajax = false;
        }


//http://en.wikipedia.org/wiki/ISO_4217
        $mode = get_option('nbtwccs_currencies_aggregator', 'google');
        $request = "";
        //$nbtwccs_use_curl = (int) get_option('nbtwccs_use_curl', 0);
        $nbtwccs_use_curl = 1;
        switch ($mode) {
            case 'yahoo':
                //dead, doesn work
//http://www.idiotinside.com/2015/01/28/create-a-currency-converter-in-php-python-javascript-and-jquery-using-yahoo-currency-api/
                $yql_base_url = "http://query.yahooapis.com/v1/public/yql";
                $yql_query = 'select * from yahoo.finance.xchange where pair in ("' . $this->default_currency . $this->escape($_REQUEST['currency_name']) . '")';
                $yql_query_url = $yql_base_url . "?q=" . urlencode($yql_query);
                $yql_query_url .= "&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";


                if (function_exists('curl_init') AND $nbtwccs_use_curl) {
                    $res = $this->file_get_contents_curl($yql_query_url);
                } else {
                    $res = file_get_contents($yql_query_url);
                }
     
                $yql_json = json_decode($res, true);
                $request = (float) $yql_json['query']['results']['rate']['Rate'];


                break;

            case 'google':
                $amount = urlencode(1);
                $from_Currency = urlencode($this->default_currency);
                $to_Currency = urlencode($this->escape($_REQUEST['currency_name']));
                //$url = "http://finance.google.com/finance/converter?a=$amount&from=$from_Currency&to=$to_Currency";
                //test mode
                $url = "https://finance.google.com/finance?q=" . $from_Currency . $to_Currency;
                if (function_exists('curl_init') AND $nbtwccs_use_curl) {
                    $html = $this->file_get_contents_curl($url);
                } else {
                    $html = file_get_contents($url);
                }
                preg_match_all('/<span class=bld>(.*?)<\/span>/s', $html, $matches);
                if (isset($matches[1][0])) {
                    $request = floatval(str_replace(",", "", $matches[1][0]));
                } else {
                    $request = sprintf(__("no data for %s", 'netbase_solutions'), $this->escape($_REQUEST['currency_name']));
                }

                break;

            case 'privatbank':
                //https://api.privatbank.ua/#p24/exchange
                $url = 'https://api.privatbank.ua/p24api/pubinfo?json&exchange&coursid=5'; //4,5

                if (function_exists('curl_init') AND $nbtwccs_use_curl) {
                    $res = $this->file_get_contents_curl($url);
                } else {
                    $res = file_get_contents($url);
                }

                $currency_data = json_decode($res, true);
                $rates = array();

                //var_dump($currency_data);
                if (!empty($currency_data)) {
                    foreach ($currency_data as $c) {
                        if ($c['base_ccy'] == 'UAH') {
                            $rates[$c['ccy']] = floatval($c['sale']);
                        }
                    }
                }

                if (!empty($rates)) {

                    if ($this->default_currency != 'UAH') {
                        if ($_REQUEST['currency_name'] != 'UAH') {
                            if (isset($_REQUEST['currency_name'])) {
                                $request = floatval($rates[$this->default_currency] / ($rates[$this->escape($_REQUEST['currency_name'])]));
                            } else {
                                $request = sprintf(__("no data for %s", 'netbase_solutions'), $this->escape($_REQUEST['currency_name']));
                            }
                        } else {
                            $request = 1 / (1 / $rates[$this->default_currency]);
                        }
                    } else {
                        if ($_REQUEST['currency_name'] != 'UAH') {
                            $request = 1 / $rates[$_REQUEST['currency_name']];
                        } else {
                            $request = 1;
                        }
                    }
                } else {
                    $request = sprintf(__("no data for %s", 'netbase_solutions'), $this->escape($_REQUEST['currency_name']));
                }

                if (!$request) {
                    $request = sprintf(__("no data for %s", 'netbase_solutions'), $this->escape($_REQUEST['currency_name']));
                }


                break;

            case 'ecb':
                $url = 'http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml';

                if (function_exists('curl_init') AND $nbtwccs_use_curl) {
                    $res = $this->file_get_contents_curl($url);
                } else {
                    $res = file_get_contents($url);
                }

                $currency_data = simplexml_load_string($res);
                $rates = array();
                if (empty($currency_data->Cube->Cube)) {
                    $request = sprintf(__("no data for %s", 'netbase_solutions'), $this->escape($_REQUEST['currency_name']));
                    break;
                }

                foreach ($currency_data->Cube->Cube->Cube as $xml) {
                    $att = (array) $xml->attributes();
                    $rates[$att['@attributes']['currency']] = floatval($att['@attributes']['rate']);
                }
                if (!empty($rates)) {

                    if ($this->default_currency != 'EUR') {
                        if ($_REQUEST['currency_name'] != 'EUR') {
                            if (isset($_REQUEST['currency_name'])) {
                                $request = floatval($rates[$this->escape($_REQUEST['currency_name'])] / $rates[$this->default_currency]);
                            } else {
                                $request = sprintf(__("no data for %s", 'netbase_solutions'), $this->escape($_REQUEST['currency_name']));
                            }
                        } else {
                            $request = 1 / $rates[$this->default_currency];
                        }
                    } else {
                        if ($_REQUEST['currency_name'] != 'EUR') {
                            if ($rates[$_REQUEST['currency_name']] < 1) {
                                $request = 1 / $rates[$_REQUEST['currency_name']];
                            } else {
                                $request = $rates[$_REQUEST['currency_name']];
                            }
                        } else {
                            $request = 1;
                        }
                    }
                } else {
                    $request = sprintf(__("no data for %s", 'netbase_solutions'), $this->escape($_REQUEST['currency_name']));
                }


                if (!$request) {
                    $request = sprintf(__("no data for %s", 'netbase_solutions'), $this->escape($_REQUEST['currency_name']));
                }


                break;

            case 'rf':
                //http://www.cbr.ru/scripts/XML_daily_eng.asp?date_req=21/08/2015
                $xml_url = 'http://www.cbr.ru/scripts/XML_daily_eng.asp?date_req='; //21/08/2015
                $date = date('d/m/Y');
                $xml_url .= $date;
                if (function_exists('curl_init') AND $nbtwccs_use_curl) {
                    $res = $this->file_get_contents_curl($xml_url);
                } else {
                    $res = file_get_contents($xml_url);
                }

                $xml = simplexml_load_string($res) or die("Error: Cannot create object");
                $xml = $this->object2array($xml);
                $rates = array();
                $nominal = array();

                if (isset($xml['Valute'])) {
                    if (!empty($xml['Valute'])) {
                        foreach ($xml['Valute'] as $value) {
                            $rates[$value['CharCode']] = floatval(str_replace(',', '.', $value['Value']));
                            $nominal[$value['CharCode']] = $value['Nominal'];
                        }
                    }
                }

                if (!empty($rates)) {
                    if ($this->default_currency != 'RUB') {
                        if ($_REQUEST['currency_name'] != 'RUB') {
                            if (isset($_REQUEST['currency_name'])) {
                                $request = $nominal[$this->escape($_REQUEST['currency_name'])] * floatval($rates[$this->default_currency] / $rates[$this->escape($_REQUEST['currency_name'])] / $nominal[$this->escape($this->default_currency)]);
                            } else {
                                $request = sprintf(__("no data for %s", 'netbase_solutions'), $this->escape($_REQUEST['currency_name']));
                            }
                        } else {
                            if ($nominal[$this->default_currency] == 10) {
                                $request = (1 / (1 / $rates[$this->default_currency])) / $nominal[$this->default_currency];
                            } else {
                                $request = 1 / (1 / $rates[$this->default_currency]);
                            }
                        }
                    } else {
                        if ($_REQUEST['currency_name'] != 'RUB') {
                            $request = $nominal[$this->escape($_REQUEST['currency_name'])] / $rates[$_REQUEST['currency_name']];
                        } else {
                            $request = 1;
                        }
                    }
                } else {
                    $request = sprintf(__("no data for %s", 'netbase_solutions'), $this->escape($_REQUEST['currency_name']));
                }

                

                if (!$request) {
                    $request = sprintf(__("no data for %s", 'netbase_solutions'), $this->escape($_REQUEST['currency_name']));
                }

                break;


            case 'bank_polski':
                //http://api.nbp.pl/en.html
                $url = 'http://api.nbp.pl/api/exchangerates/tables/A'; //A,B

                if (function_exists('curl_init') AND $nbtwccs_use_curl) {
                    $res = $this->file_get_contents_curl($url);
                } else {
                    $res = file_get_contents($url);
                }

                $currency_data = json_decode($res, TRUE);
                $rates = array();
                if (!empty($currency_data[0])) {
                    foreach ($currency_data[0]['rates'] as $c) {
                        $rates[$c['code']] = floatval($c['mid']);
                    }
                }               

                if (!empty($rates)) {

                    if ($this->default_currency != 'PLN') {
                        if ($_REQUEST['currency_name'] != 'PLN') {
                            if (isset($_REQUEST['currency_name'])) {
                                $request = floatval($rates[$this->default_currency] / ($rates[$this->escape($_REQUEST['currency_name'])]));
                            } else {
                                $request = sprintf(__("no data for %s", 'netbase_solutions'), $this->escape($_REQUEST['currency_name']));
                            }
                        } else {
                            $request = 1 / (1 / $rates[$this->default_currency]);
                        }
                    } else {
                        if ($_REQUEST['currency_name'] != 'PLN') {
                            $request = 1 / $rates[$_REQUEST['currency_name']];
                        } else {
                            $request = 1;
                        }
                    }
                } else {
                    $request = sprintf(__("no data for %s", 'netbase_solutions'), $this->escape($_REQUEST['currency_name']));
                }

                

                if (!$request) {
                    $request = sprintf(__("no data for %s", 'netbase_solutions'), $this->escape($_REQUEST['currency_name']));
                }

                break;
            case'free_converter':
                $from_Currency = urlencode($this->default_currency);
                $to_Currency = urlencode($this->escape($_REQUEST['currency_name']));
                $query_str = sprintf("%s_%s", $from_Currency, $to_Currency);
                $url = "http://free.currencyconverterapi.com/api/v3/convert?q={$query_str}&compact=y";

                if (function_exists('curl_init') AND $nbtwccs_use_curl) {
                    $res = $this->file_get_contents_curl($url);
                } else {
                    $res = file_get_contents($url);
                }

                $currency_data = json_decode($res, true);

                if (!empty($currency_data[$query_str]['val'])) {
                    $request = $currency_data[$query_str]['val'];
                } else {
                    $request = sprintf(__("no data for %s", 'netbase_solutions'), $this->escape($_REQUEST['currency_name']));
                }                

                if (!$request) {
                    $request = sprintf(__("no data for %s", 'netbase_solutions'), $this->escape($_REQUEST['currency_name']));
                }
                break;

            default:
                break;
        }

        if ($is_ajax) {
            echo $request;
            exit;
        } else {
            return $request;
        }
    }

    private function object2array($object) {
        return @json_decode(@json_encode($object), 1);
    }

//ajax
    public function save_etalon() {
        if (!is_ajax() OR ! current_user_can('manage_options')) {
//we need it just only for ajax update
            return "";
        }
        $currencies = $this->get_currencies();
        $currency_name = $this->escape($_REQUEST['currency_name']);
        foreach ($currencies as $key => $currency) {
            if ($currency['name'] == $currency_name) {
                $currencies[$key]['is_etalon'] = 1;
            } else {
                $currencies[$key]['is_etalon'] = 0;
            }
        }
        update_option('nbtwccs', $currencies);
//+++ get curr updated values back
        $request = array();
        $this->default_currency = strtoupper($this->escape($_REQUEST['currency_name']));
        $_REQUEST['no_ajax'] = TRUE;
        foreach ($currencies as $key => $currency) {
            if ($currency_name != $currency['name']) {
                $_REQUEST['currency_name'] = $currency['name'];
                $request[$key] = $this->get_rate();
            } else {
                $request[$key] = 1;
            }
        }

        echo json_encode($request);
        exit;
    }

//order data registration
    public function woocommerce_thankyou_order_id($order_id) {
        $currencies = $this->get_currencies();
        update_post_meta($order_id, '_nbtwccs_order_rate', $currencies[$this->current_currency]['rate']);
        wc_add_order_item_meta($order_id, '_nbtwccs_order_rate', $currencies[$this->current_currency]['rate'], true);
        update_post_meta($order_id, '_nbtwccs_order_base_currency', $this->default_currency);
        wc_add_order_item_meta($order_id, '_nbtwccs_order_base_currency', $this->default_currency, true);
        update_post_meta($order_id, '_nbtwccs_order_currency_changed_mannualy', 0);
        wc_add_order_item_meta($order_id, '_nbtwccs_order_currency_changed_mannualy', 0, true);

        return $order_id;
    }

    public function woocommerce_cart_totals_order_total_html($output) {
//if ($this->current_currency == $this->default_currency)
        {
            return $output;
        }
//experimental feature. Do not use it.

        $value = "&nbsp;(";

        $currencies = $this->get_currencies();
        $amount = WC()->cart->total / $currencies[$this->current_currency]['rate'];

        $cc = $this->current_currency;
        $this->current_currency = $this->default_currency;
        $value .= __('Total in basic currency: ', 'netbase_solutions') . $this->wc_price($amount, false, array('currency' => $this->default_currency));
        $this->current_currency = $cc;
        $value .= ")";
        return $output . $value;
    }

    public function wc_price_args($default_args) {
        if (in_array($this->current_currency, $this->no_cents)) {
            $default_args['decimals'] = 0;
        }
        return $default_args;
    }

//***************************** email actions

    public function woocommerce_email_actions($email_actions) {
        $_REQUEST['nbtwccs_order_emails_is_sending'] = 1;
        if (isset($_REQUEST['nbtwccs_in_order_currency'])) {
            $this->current_currency = $_REQUEST['nbtwccs_in_order_currency'];            
        } else {
            global $post;
            if (is_object($post) AND $post->post_type == 'shop_order') {
                //processing button pressed in: wp-admin/edit.php?post_type=shop_order
                $currency = get_post_meta($post->ID, '_order_currency', true);
                if (!empty($currency)) {
                    $_REQUEST['nbtwccs_in_order_currency'] = $currency;
                    $this->current_currency = $currency;
                }
            } else {                
                if (isset($_POST['order_status']) AND isset($_POST['post_ID'])) {
                    $currency = get_post_meta((int) $_POST['post_ID'], '_order_currency', true);                    
                    if (!empty($currency)) {
                        $_REQUEST['nbtwccs_in_order_currency'] = $currency;
                        $this->current_currency = $currency;
                    }
                }
            }
        }

        return $email_actions;
    }

    public function woocommerce_before_resend_order_emails($order) {
        $order_id = 0;
        if (method_exists($order, 'get_id')) {
            $order_id = $order->get_id();
        } else {
            $order_id = $order->id;
        }

        $currency = get_post_meta($order_id, '_order_currency', true);
        if (!empty($currency)) {
            $_REQUEST['nbtwccs_in_order_currency'] = $currency;
            $this->current_currency = $currency;
            $this->default_currency = $currency;
        }
    }

//when admin complete order
    public function woocommerce_order_status_completed($order_id) {
        if (get_option('nbtwccs_is_multiple_allowed', 0)) {
            $currency = get_post_meta($order_id, '_order_currency', true);
            if (!empty($currency)) {
                $_REQUEST['nbtwccs_in_order_currency'] = $currency;
                $this->default_currency = $currency;
            }
        }
    }

//wp-content\plugins\woocommerce\includes\class-wc-emails.php

    public function woocommerce_order_status_completed_notification($args) {
        if (get_option('nbtwccs_is_multiple_allowed', 0)) {
            $order_id = $args;
            $currency = get_post_meta($order_id, '_order_currency', true);
            if (!empty($currency)) {
                $_REQUEST['nbtwccs_in_order_currency'] = $currency;
                $this->default_currency = $currency;
                $this->current_currency = $currency;
            }
        }
    }

//********************************************************************************

    public function wp_footer() {

        if (isset($_GET['currency'])) {
            ?>
            <script type="text/javascript">
                try {
                    jQuery(function () {
                        try {
                            //https://wordpress.org/support/topic/wrong-cookie-leads-to-ajax-request-on-every-page/
                            jQuery.cookie('woocommerce_cart_hash', '', {path: '/'});
                        } catch (e) {
                            console.log(e);
                        }
                    });
                } catch (e) {
                    console.log(e);
                }
            </script>
            <?php
        }
    }

//********************************************************************************

    public function render_html($pagepath, $data = array()) {
        @extract($data);
        ob_start();
        include($pagepath);
        return ob_get_clean();
    }

    public function get_sign_rate($atts) {
        $sign = strtoupper($atts['sign']);
        $currencies = $this->get_currencies();
        $rate = 0;
        if (isset($currencies[$sign])) {
            $rate = $currencies[$sign]['rate'];
        }

        return $rate;
    }

//for hook woocommerce_paypal_args
    function apply_conversion($paypal_args) {
        if (in_array($this->current_currency, $this->no_cents)) {
            $paypal_args['currency_code'] = $this->current_currency;
            foreach ($paypal_args as $key => $value) {
                if (strpos($key, 'amount_') !== false) {
                    $paypal_args[$key] = number_format($value, 0, $this->decimal_sep, '');
                } else {
                    if (strpos($key, 'tax_cart') !== false) {
                        $paypal_args[$key] = number_format($value, 0, $this->decimal_sep, '');
                    }
                }
            }
        }

        return $paypal_args;
    }

    public function woocommerce_price_html($price_html, $product) {

        static $customer_price_format = -1;
        if ($customer_price_format === -1) {
            /*$customer_price_format = get_option('nbtwccs_customer_price_format', '__PRICE__');*/
            $customer_price_format = '__PRICE__';
        }

        if (empty($customer_price_format)) {
            $customer_price_format = '__PRICE__';
        }

        $currencies = $this->get_currencies();
        $product_id = $product->get_id();


        if (!empty($customer_price_format)) {
            $txt = '<span class="nbtwccs_price_code" data-product-id="' . $product_id . '">' . $customer_price_format . '</span>';
            $txt = str_replace('__PRICE__', $price_html, $txt);
            $price_html = str_replace('__CODE__', $this->current_currency, $txt);
            $price_html = apply_filters('nbtwccs_price_html_tail', $price_html);
        }

//hide cents on front as html element
        if (!in_array($this->current_currency, $this->no_cents)) {
            $sep = wc_get_price_decimal_separator();
            $zeros = str_repeat('[0-9]', $this->get_currency_price_num_decimals($this->current_currency));
            if ($currencies[$this->current_currency]['hide_cents'] == 1) {
                $price_html = preg_replace("/\\{$sep}{$zeros}/", '', $price_html);
            }
        }

//add additional info in price html
        if (get_option('nbtwccs_price_info', 0) AND ! (is_admin() AND ! isset($_REQUEST['get_product_price_by_ajax'])) AND ! isset($_REQUEST['hide_nbtwccs_price_info_list'])) {
            $info = "<ul class='nbtwccs_price_info_list'>";
            $current_currency = $this->current_currency;

            foreach ($currencies as $сurr) {

                if ($сurr['name'] == $current_currency) {
                    continue;
                }
                $this->current_currency = $сurr['name'];

                $value = (float) $product->get_price('edit') * (float) $currencies[$сurr['name']]['rate'];

                $precision = $this->get_currency_price_num_decimals($сurr['name'], $this->price_num_decimals);
                $value = number_format($value, $precision, $this->decimal_sep, '');                

                $product_type = '';
                $product_type = $product->get_type();

                if ($product_type == 'variable') {

                    $min_value = $product->get_variation_price('min', true) * $currencies[$сurr['name']]['rate'];
                    $max_value = $product->get_variation_price('max', true) * $currencies[$сurr['name']]['rate'];

                    
                    $min_max_values = $this->_get_min_max_variation_prices($product, $сurr['name']);
                    if (!empty($min_max_values)) {
                        //echo '<pre>' . print_r($min_max_values, true) . '</pre>';
                        $min_value = $min_max_values['min'] /* $currencies[$сurr['name']]['rate'] */;
                        $max_value = $min_max_values['max'] /* $currencies[$сurr['name']]['rate'] */;
                    }
                    if (wc_tax_enabled()) {
                        $min_value = $this->nbtwccs_calc_tax_price($product, $min_value);
                        $max_value = $this->nbtwccs_calc_tax_price($product, $max_value);
                    }
                    
                    $_REQUEST['nbtwccs_wc_price_convert'] = FALSE;

                    $var_price = "";
                    $var_price1 = $this->wc_price($min_value, array('currency' => $сurr['name']), false, $product, $precision);
                    $var_price2 = $this->wc_price($max_value, array('currency' => $сurr['name']), false, $product, $precision);
                    if ($var_price1 == $var_price2) {
                        $var_price = $var_price1;
                    } else {
                        $var_price = sprintf("%s - %s", $var_price1, $var_price2);
                    }

                    unset($_REQUEST['nbtwccs_wc_price_convert']);
                    $info .= "<li><b>" . $сurr['name'] . "</b>: " . $var_price . "</li>";
                } elseif ($product_type == 'grouped') {

                    $child_ids = $product->get_children();
                    $prices = array();
                    foreach ($child_ids as $prod_id) {
                        $product1 = get_product($prod_id);
                        $product_type1 = $product1->get_type();
                        if ($product_type1 == 'variable') {

                            $min_value = $product1->get_variation_price('min', true) * $currencies[$сurr['name']]['rate'];
                            $max_value = $product1->get_variation_price('max', true) * $currencies[$сurr['name']]['rate'];
                            
                            $min_max_values = $this->_get_min_max_variation_prices($product1, $сurr['name']);
                            if (!empty($min_max_values)) {
                                //echo '<pre>' . print_r($min_max_values, true) . '</pre>';
                                $min_value = $min_max_values['min'] /* $currencies[$сurr['name']]['rate'] */;
                                $max_value = $min_max_values['max'] /* $currencies[$сurr['name']]['rate'] */;
                            }
                            if (wc_tax_enabled()) {
                                $prices[] = $this->nbtwccs_calc_tax_price($product1, $min_value);
                                $prices[] = $this->nbtwccs_calc_tax_price($product1, $max_value);
                            } else {
                                $prices[] = $min_value;
                                $prices[] = $max_value;
                            }
                        } else {

                            if ($this->is_fixed_enabled AND $this->is_multiple_allowed) {
                                $type = 'sale';
                                $is_empty = $this->fixed->is_empty($prod_id, $сurr['name'], $type);
                                $is_exists = $this->fixed->is_exists($prod_id, $сurr['name'], $type);

                                if ($type == 'sale' AND $is_empty) {
                                    $type = 'regular';
                                    $is_exists = $this->fixed->is_exists($prod_id, $сurr['name'], $type);
                                    $is_empty = $this->fixed->is_empty($prod_id, $сurr['name'], $type);
                                }

                                if ($is_exists AND ! $is_empty) {
                                    $special_convert = true;
                                    $is_price_custom = true;
                                    if (floatval($this->fixed->get_value($prod_id, $сurr['name'], $type)) > 0) {

                                        if (wc_tax_enabled()) {
                                            $prices[] = $this->nbtwccs_calc_tax_price($product1, floatval($this->fixed->get_value($prod_id, $сurr['name'], $type)));
                                        } else {
                                            $prices[] = floatval($this->fixed->get_value($prod_id, $сurr['name'], $type));
                                        }
                                    }
                                } else {
                                    if (wc_tax_enabled()) {
                                        $prices[] = $this->nbtwccs_calc_tax_price($product1, $product1->get_price('edit') * $currencies[$сurr['name']]['rate']);
                                    } else {
                                        $prices[] = $product1->get_price('edit') * $currencies[$сurr['name']]['rate'];
                                    }
                                }
                            } else {
                                if (wc_tax_enabled()) {
                                    $prices[] = $this->nbtwccs_calc_tax_price($product1, $product1->get_price('edit') * $currencies[$сurr['name']]['rate']);
                                } else {
                                    $prices[] = $product1->get_price('edit') * $currencies[$сurr['name']]['rate'];
                                }
                            }
                        }
                    }
                    asort($prices);
                    $_REQUEST['nbtwccs_wc_price_convert'] = FALSE;
                    $var_price = "";
                    $var_price1 = $this->wc_price(array_shift($prices), array('currency' => $сurr['name']), false, $product, $precision);
                    $var_price2 = $this->wc_price(array_pop($prices), array('currency' => $сurr['name']), false, $product, $precision);

                    if ($var_price1 == $var_price2) {
                        $var_price = $var_price1;
                    } else {
                        $var_price = sprintf("%s - %s", $var_price1, $var_price2);
                    }

                    $info .= "<li><b>" . $сurr['name'] . "</b>: " . $var_price . "</li>";
                } else {                    
                    if (wc_tax_enabled()) {
                        $value = $this->nbtwccs_calc_tax_price($product, $value);
                    }
                    $info .= "<li><span>" . $сurr['name'] . "</span>: " . $this->wc_price($value, false, array('currency' => $сurr['name']), $product, $precision) . "</li>";
                }
            }
            $this->current_currency = $current_currency;
            $info .= "</ul>";
            $info = '<div class="nbtwccs_price_info"><span class="nbtwccs_price_info_icon"></span>' . $info . '</div>';
            $price_html .= $info;
        }


        return $price_html;
    }

    public function woocommerce_coupon_get_discount_amount($discount, $discounting_amount, $cart_item, $single, $coupon) {
        if ($this->is_multiple_allowed) {
            if (is_object($coupon) AND method_exists($coupon, 'is_type')) {
                if (!$coupon->is_type(array('percent_product', 'percent'))) {
                    $discount = $this->nbtwccs_exchange_value(floatval($discount));
                }
            }
        }

        return $discount;
    }

    public function woocommerce_coupon_validate_minimum_amount($is, $coupon) {

        if ($this->current_currency != $this->default_currency AND get_option('nbtwccs_is_multiple_allowed', 0)) {
            $currencies = $this->get_currencies();
            //convert amount into basic currency amount
            $cart_amount = $this->back_convert(WC()->cart->get_displayed_subtotal(), $currencies[$this->current_currency]['rate']);
            return $coupon->get_minimum_amount() > $cart_amount;
        }

        return $is;
    }

    public function woocommerce_coupon_validate_maximum_amount($is, $coupon) {

        if ($this->current_currency != $this->default_currency AND get_option('nbtwccs_is_multiple_allowed', 0)) {
            $currencies = $this->get_currencies();
            //convert amount into basic currency amount
            $cart_amount = $this->back_convert(WC()->cart->get_displayed_subtotal(), $currencies[$this->current_currency]['rate']);
            return $coupon->get_maximum_amount() < $cart_amount;
        }

        return $is;
    }

    public function woocommerce_coupon_error($err, $err_code, $coupon) {
        if ($this->current_currency != $this->default_currency) {
            $currencies = $this->get_currencies();

            $rate = 1;
            if (get_option('nbtwccs_is_multiple_allowed', 0)) {
                $rate = $currencies[$this->current_currency]['rate'];
            }

            switch ($err_code) {
                case 112:

                    $amount = $coupon->get_maximum_amount() * $rate;
                    $err = sprintf(__('The maximum spend for this coupon is %s.', 'netbase_solutions'), wc_price($amount));
                    break;

                case 108:
                    $amount = $coupon->get_minimum_amount() * $rate;
                    $err = sprintf(__('The minimum spend for this coupon is %s.', 'netbase_solutions'), wc_price($amount));
                    break;

                default:
                    break;
            }
        }

        return $err;
    }

//wp filter for values which is in basic currency and no possibility do it automatically
    public function nbtwccs_exchange_value($value) {
        $currencies = $this->get_currencies();
        $value = floatval($value) * floatval($currencies[$this->current_currency]['rate']);
        $precision = $this->get_currency_price_num_decimals($this->current_currency, $this->price_num_decimals);
        $value = number_format($value, $precision, $this->decimal_sep, '');
        return $value;
    }

//set it to default
    public function reset_currency() {
        $this->set_currency('');
    }

    public function set_currency($currency = '') {
        if (empty($currency)) {
            $currency = $this->default_currency;
        }
        $this->storage->set_val('nbtwccs_current_currency', $currency);
        $this->current_currency = $currency;
    }

//compatibility for https://wordpress.org/plugins/woocommerce-pdf-invoices-packing-slips/stats/
//hook commented, wpo_wcpdf_process_template_order uses for this
    public function wpo_wcpdf_order_number($order_id) {
//set order currency instead selected on the front
        $currency = get_post_meta($order_id, '_order_currency', TRUE);
        if (!empty($currency)) {
            $this->current_currency = $currency;
        }

        return $order_id;
    }

//https://wordpress.org/support/topic/multi-currency-on-invoices?replies=8
    public function wpo_wcpdf_process_template_order($template_type, $order_id) {
        if (!empty($order_id) AND is_numeric($order_id)) {
            $currency = get_post_meta($order_id, '_order_currency', TRUE);
            if (!empty($currency)) {
                $this->current_currency = $currency;
            }
        }
    }

    public function woocommerce_get_order_currency($order_currency, $order) {

        if (!is_ajax() AND ! is_admin() AND is_object($order)) {
            $order_id = 0;
            if (method_exists($order, 'get_id')) {
                $order_id = $order->get_id();
            } else {
                $order_id = $order->id;
            }

            $currency = get_post_meta($order_id, '_order_currency', TRUE);
            if (!empty($currency)) {
                $this->current_currency = $currency;
            }
        }

        return $order_currency;
    }

    public function woocommerce_view_order($order_id) {

        if (!is_ajax() AND ! is_admin()) {
            $currency = get_post_meta($order_id, '_order_currency', TRUE);
            if (!empty($currency)) {
                $this->current_currency = $currency;
            }
        }

        return $order_id;
    }

    public function woocommerce_package_rates($rates) {
        $currencies = $this->get_currencies();
        $new_version = false;
        $new_version = true;


        if ($this->is_multiple_allowed) {
            if ($this->current_currency != $this->default_currency) {
                $currencies = $this->get_currencies();
                foreach ($rates as $rate) {

                    $value = $rate->cost * $currencies[$this->current_currency]['rate'];
                    if ($this->is_fixed_shipping) {//is fixed shipping cost
                        $is_empty = $this->fixed_shipping->is_empty($rate->id, $this->current_currency, '');
                        $is_exist = $this->fixed_shipping->is_exists($rate->id, $this->current_currency, '');
                        if (!$is_empty AND $is_exist) {
                            $value = $this->fixed_shipping->get_value($rate->id, $this->current_currency, '');
                        }
                    }
                    $precision = $this->get_currency_price_num_decimals($this->current_currency, $this->price_num_decimals);
                    $rate->cost = number_format(floatval($value), $precision, $this->decimal_sep, '');
//VAT values for another currency in the shipping
//https://wordpress.org/support/topic/vat-values-are-not-switched-to-another-currency-for-shipping

                    if (isset($rate->taxes)) {
                        $taxes = $rate->taxes;
                        if (!empty($taxes)) {
                            $new_tax = array();
                            if ($this->is_fixed_shipping AND ! $is_empty AND $is_exist AND $value) {
                                if (wc_tax_enabled() AND ! WC()->customer->is_vat_exempt() AND is_array($rate->taxes)) {
                                    $new_tax = WC_Tax::calc_shipping_tax($value, WC_Tax::get_shipping_tax_rates());
                                }
                            } else {
                                foreach ($taxes as $order => $tax) {
                                    $value_tax = $tax * $currencies[$this->current_currency]['rate'];
                                    $sum = number_format(floatval($value_tax), $precision, $this->decimal_sep, '');
                                    if ($new_version) {
                                        $new_tax[$order] = $sum;
                                    } else {
                                        $rate->taxes[$order] = $sum;
                                    }
                                }
                            }
                            if ($new_version) {
                                $rate->set_taxes($new_tax);
                            }
                        }
                    }
                }
            }
        }

        return $rates;
    }

    public function wcml_raw_price_amount($value) {
        return $this->nbtwccs_exchange_value($value);
    }

//ajax
    public function nbtwccs_convert_currency() {
        $currencies = $this->get_currencies();
        $v = $currencies[$_REQUEST['to']]['rate'] / $currencies[$_REQUEST['from']]['rate'];
        if (in_array($_REQUEST['to'], $this->no_cents)) {
            $_REQUEST['precision'] = 0;
        }
        $value = number_format($v * $_REQUEST['amount'], intval($_REQUEST['precision']), $this->decimal_sep, '');


        wp_die($value);
    }

//for refreshing mini-cart widget
    public function woocommerce_before_mini_cart() {
        $_REQUEST['nbtwccs_woocommerce_before_mini_cart'] = 'mini_cart_refreshing';
        WC()->cart->calculate_totals();
    }

//for refreshing mini-cart widget
    public function woocommerce_after_mini_cart() {
        unset($_REQUEST['nbtwccs_woocommerce_before_mini_cart']);
    }

//ajax
    public function nbtwccs_rates_current_currency() {
        wp_die(do_shortcode('[nbtwccs_rates exclude="' . $this->escape($_REQUEST['exclude']) . '" precision="' . $this->escape($_REQUEST['precision']) . '" current_currency="' . $this->escape($_REQUEST['current_currency']) . '"]'));
    }

//log test data while makes debbuging
    public function log($string) {
        $handle = fopen(NBTWCCS_PATH . 'log.txt', 'a+');
        $string .= PHP_EOL;
        fwrite($handle, $string);
        fclose($handle);
    }

    public function wc_price($price, $convert = true, $args = array(), $product = NULL, $decimals = -1) {
        if (!isset($_REQUEST['nbtwccs_wc_price_convert'])) {
            $_REQUEST['nbtwccs_wc_price_convert'] = true;
        }
        extract(apply_filters('wc_price_args', wp_parse_args($args, array(
            'ex_tax_label' => false,
            'currency' => '',
            'decimal_separator' => $this->decimal_sep,
            'thousand_separator' => $this->thousands_sep,
            'decimals' => $decimals,
            'price_format' => $this->woocommerce_price_format()
        ))));

        if ($decimals < 0) {
            $decimals = $this->get_currency_price_num_decimals($currency, $this->price_num_decimals);
        }


        $currencies = $this->get_currencies();
        if (isset($currencies[$currency])/* AND !isset($_REQUEST['nbtwccs_show_custom_price']) */) {
            if ($currencies[$currency]['hide_cents']) {
                $decimals = 0;
            }
        }


        $negative = $price < 0;
        $special_convert = false;
        $is_price_custom = false;
        try {
            if ($product !== NULL AND is_object($product)) {

                $product_id = $product->get_id();

                
                if ($this->is_multiple_allowed) {
                    if ($this->is_fixed_enabled) {                        
                        $type = 'sale';

                        $is_empty = $this->fixed->is_empty($product_id, $currency, $type);
                        $is_exists = $this->fixed->is_exists($product_id, $currency, $type);

                        if ($type == 'sale' AND $is_empty) {
                            $type = 'regular';
                            $is_exists = $this->fixed->is_exists($product_id, $currency, $type);
                            $is_empty = $this->fixed->is_empty($product_id, $currency, $type);
                        }

                        if ($is_exists AND ! $is_empty) {
                            $special_convert = true;
                            $is_price_custom = true;
                            if (floatval($this->fixed->get_value($product_id, $currency, $type)) > 0) {
                                $price = floatval($this->fixed->get_value($product_id, $currency, $type));
                                if (wc_tax_enabled()) {
                                    $price = $this->nbtwccs_calc_tax_price($product, $price);
                                }
                            }
                        }
                    }
                }
            }
        } catch (Exception $e) {
            
        }        

        if ($this->is_geoip_manipulation AND ! $is_price_custom AND ! is_null($product)) {
            $product_geo_price_data = $this->_get_product_geo_price($product, $price, 'sale', true);
            $price = $product_geo_price_data[0];
            $is_price_custom = true;
            
            $product_type = 'simple';

            $product_type = $product->get_type();

            if ($product_type == 'variable') {
                if ($product_geo_price_data[1]) {
                    $is_price_custom = false;
                }
            } else {
                if ($product_geo_price_data[1]) {
                    $price = $this->raw_woocommerce_price(floatval($negative ? $price * -1 : $price));
                    if (wc_tax_enabled()) {
                        $price = $this->nbtwccs_calc_tax_price($product, $price);
                    }
                }
            }
        }        

        if ($convert AND $_REQUEST['nbtwccs_wc_price_convert'] AND ! $is_price_custom) {
            $price = $this->raw_woocommerce_price(floatval($negative ? $price * -1 : $price));
        }        

        $price = apply_filters('formatted_woocommerce_price', number_format($price, $decimals, $decimal_separator, $thousand_separator), $price, $decimals, $decimal_separator, $thousand_separator);


        if (apply_filters('woocommerce_price_trim_zeros', false) AND $decimals > 0) {
            $price = wc_trim_zeros($price);
        }

        $formatted_price = ( $negative ? '-' : '' ) . sprintf($price_format, get_woocommerce_currency_symbol($currency), $price);
        $return = '<span class="nbtwccs_amount">' . $formatted_price . '</span>';

        if ($ex_tax_label && wc_tax_enabled()) {
            $return .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
        }       

        return apply_filters('wc_price', $return, $price, $args);
    }

    public function woocommerce_available_variation($variation_data, $product, $variation) {

        $_REQUEST['nbtwccs_woocommerce_available_variation_is'] = TRUE;
        add_filter('raw_woocommerce_price', array($this, 'raw_woocommerce_price'), 9999);
        $variation = wc_get_product($variation->get_id());

        // See if prices should be shown for each variation after selection.
        $show_variation_price = apply_filters('woocommerce_show_variation_price', $variation->get_price() === "" || $product->get_variation_sale_price('min') !== $product->get_variation_sale_price('max') || $product->get_variation_regular_price('min') !== $product->get_variation_regular_price('max'), $product, $variation);

        $_REQUEST['hide_nbtwccs_price_info_list'] = true;
        $variation_data = apply_filters('nbtwccs_woocommerce_available_variation', array_merge($variation->get_data(), array(
            'attributes' => $variation->get_variation_attributes(),
            'image' => wc_get_product_attachment_props($variation->get_image_id()),
            'weight_html' => wc_format_weight($variation->get_weight()),
            'dimensions_html' => wc_format_dimensions($variation->get_dimensions(false)),
            'price_html' => $show_variation_price ? '<span class="price">' . $variation->get_price_html() . '</span>' : '',
            'availability_html' => wc_get_stock_html($variation),
            'variation_id' => $variation->get_id(),
            'variation_is_visible' => $variation->variation_is_visible(),
            'variation_is_active' => $variation->variation_is_active(),
            'is_purchasable' => $variation->is_purchasable(),
            'display_price' => wc_get_price_to_display($variation),
            'display_regular_price' => wc_get_price_to_display($variation, array('price' => $variation->get_regular_price())),
            'dimensions' => wc_format_dimensions($variation->get_dimensions(false)),
            'min_qty' => $variation->get_min_purchase_quantity(),
            'max_qty' => 0 < $variation->get_max_purchase_quantity() ? $variation->get_max_purchase_quantity() : '',
            'backorders_allowed' => $variation->backorders_allowed(),
            'is_in_stock' => $variation->is_in_stock(),
            'is_downloadable' => $variation->is_downloadable(),
            'is_virtual' => $variation->is_virtual(),
            'is_sold_individually' => $variation->is_sold_individually() ? 'yes' : 'no',
            'variation_description' => $variation->get_description(),
                )), $product, $variation);

        unset($_REQUEST['hide_nbtwccs_price_info_list']);
        unset($_REQUEST['nbtwccs_woocommerce_available_variation_is']);
        remove_filter('raw_woocommerce_price', array($this, 'raw_woocommerce_price'), 9999);

        
        return apply_filters('nbtwccs_woocommerce_available_variation', $variation_data, $product, $variation);
    }

    public function woocommerce_product_is_on_sale($value, $product) {
        $is_sale = false;
        $sale_price = $product->sale_price;
        $regular_price = $product->regular_price;
        $price = $product->price;
//https://www.skyverge.com/blog/get-a-list-of-woocommerce-sale-products/
        if ($product->product_type == 'variable') {
            
        } else {
            if ($sale_price !== $regular_price AND ( $price === $sale_price)) {
                $is_sale = true;
            }
        }
        return $is_sale;
    }

//woo hook
//wp-content\plugins\woocommerce\includes\shipping\free-shipping\class-wc-shipping-free-shipping.php #192
    public function woocommerce_shipping_free_shipping_is_available($is_available, $package, $this_shipping = null) {
        global $woocommerce;
        $currencies = $this->get_currencies(); {
            $has_coupon = false;
            $has_met_min_amount = false;

            if (in_array($this_shipping->requires, array('coupon', 'either', 'both'))) {
                if ($coupons = WC()->cart->get_coupons()) {
                    foreach ($coupons as $code => $coupon) {
                        if ($coupon->is_valid() && $coupon->get_free_shipping()) {
                            $has_coupon = true;
                            break;
                        }
                    }
                }
            }

            if (in_array($this_shipping->requires, array('min_amount', 'either', 'both'))) {
                $total = WC()->cart->get_displayed_subtotal();
                if ($this->is_multiple_allowed) {
                    if ($this->current_currency != $this->default_currency) {
                        $total = (float) $this->back_convert($total, $currencies[$this->current_currency]['rate']);
                        //$amount = $amount + $amount * 0.001; //correction because of cents
                    }
                }
                if ('incl' === WC()->cart->tax_display_cart) {
                    $total = round($total - ( WC()->cart->get_discount_total() + WC()->cart->get_discount_tax() ), wc_get_price_decimals());
                } else {
                    $total = round($total - WC()->cart->get_discount_total(), wc_get_price_decimals());
                }
                $min_amount = $this_shipping->min_amount;

                if ($this->is_fixed_shipping) {//is fixed shipping min_amount
                    $is_empty = $this->fixed_shipping_free->is_empty($this_shipping->get_instance_option_key(), $this->current_currency, '');
                    $is_exist = $this->fixed_shipping_free->is_exists($this_shipping->get_instance_option_key(), $this->current_currency, '');
                    if (!$is_empty AND $is_exist) {
                        $min_amount = $this->fixed_shipping_free->get_value($this_shipping->get_instance_option_key(), $this->current_currency, '');
                        if ($this->current_currency != $this->default_currency) {
                            $min_amount = (float) $this->back_convert($min_amount, $currencies[$this->current_currency]['rate']);
                            //$amount = $amount + $amount * 0.001; //correction because of cents
                        }
                    }
                }
                if ($total >= $min_amount) {
                    $has_met_min_amount = true;
                }
            }

            switch ($this_shipping->requires) {
                case 'min_amount' :
                    $is_available = $has_met_min_amount;
                    break;
                case 'coupon' :
                    $is_available = $has_coupon;
                    break;
                case 'both' :
                    $is_available = $has_met_min_amount && $has_coupon;
                    break;
                case 'either' :
                    $is_available = $has_met_min_amount || $has_coupon;
                    break;
                default :
                    $is_available = true;
                    break;
            }
        }



        return $is_available;
    }

//ajax
//for price redrawing on front if site using cache plugin functionality
    public function nbtwccs_get_products_price_html() {
        $result = array();
        if (isset($_REQUEST['products_ids'])) {

            $this->init_geo_currency();

            $_REQUEST['get_product_price_by_ajax'] = 1;

//add_action('woocommerce_price_html', array($this, 'woocommerce_price_html'), 1, 2);

            $products_ids = $_REQUEST['products_ids'];

            if (!empty($products_ids) AND is_array($products_ids)) {
                foreach ($products_ids as $p_id) {
                    $product = wc_get_product($p_id);
                    if (is_object($product)) {
                        $result[$p_id] = $product->get_price_html();
                    }
                }
            }
        }

        $data = array();
        $data['ids'] = $result;
        $data['current_currency'] = $this->current_currency;
        wp_die(json_encode($data));
    }

//count amount in basic currency from any currency
    public function back_convert($amount, $rate, $precision = 4) {
        return number_format((1 / $rate) * $amount, $precision, '.', '');
    }

//recalculation order to basic currency data if order is in any another currency
    public function recalculate_order($order_id) {

        $order_currency = get_post_meta($order_id, '_order_currency', true);
//lets avoid recalculation for order which is already in
        if ($order_currency == $this->default_currency OR empty($order_currency)) {
            return;
        }
        $decimals = $this->get_currency_price_num_decimals($order_currency, $this->price_num_decimals);


        $currencies = $this->get_currencies();
        $_nbtwccs_order_rate = get_post_meta($order_id, '_nbtwccs_order_rate', true);
        if (empty($_nbtwccs_order_rate)) {
            $_nbtwccs_order_rate = $currencies[$order_currency]['rate'];
        }


        update_post_meta($order_id, '_nbtwccs_order_currency', $this->default_currency);
        update_post_meta($order_id, '_order_currency', $this->default_currency);

        update_post_meta($order_id, '_nbtwccs_order_base_currency', $this->default_currency);
        wc_update_order_item_meta($order_id, '_nbtwccs_order_base_currency', $this->default_currency);

        update_post_meta($order_id, '_nbtwccs_order_rate', 1);
        wc_update_order_item_meta($order_id, '_nbtwccs_order_rate', 1);

        update_post_meta($order_id, '_nbtwccs_order_currency_changed_mannualy', time());
        wc_add_order_item_meta($order_id, '_nbtwccs_order_currency_changed_mannualy', time(), true);



        $_order_shipping = get_post_meta($order_id, '_order_shipping', true);
        update_post_meta($order_id, '_order_shipping', $this->back_convert($_order_shipping, $_nbtwccs_order_rate));

        $_order_total = get_post_meta($order_id, '_order_total', true);
        update_post_meta($order_id, '_order_total', $this->back_convert($_order_total, $_nbtwccs_order_rate));

        $_refund_amount = get_post_meta($order_id, '_refund_amount', true);
        update_post_meta($order_id, '_refund_amount', $this->back_convert($_refund_amount, $_nbtwccs_order_rate));

        $_cart_discount_tax = get_post_meta($order_id, '_cart_discount_tax', true);
        update_post_meta($order_id, '_cart_discount_tax', $this->back_convert($_cart_discount_tax, $_nbtwccs_order_rate));

        $_order_tax = get_post_meta($order_id, '_order_tax', true);
        update_post_meta($order_id, '_order_tax', $this->back_convert($_order_tax, $_nbtwccs_order_rate));

        $_order_shipping_tax = get_post_meta($order_id, '_order_shipping_tax', true);
        update_post_meta($order_id, '_order_shipping_tax', $this->back_convert($_order_shipping_tax, $_nbtwccs_order_rate));

        $_cart_discount = get_post_meta($order_id, '_cart_discount', true);
        update_post_meta($order_id, '_cart_discount', $this->back_convert($_cart_discount, $_nbtwccs_order_rate));

        global $wpdb;
        $data_sql = array(
            array(
                'val' => $order_id,
                'type' => 'int',
            ),
        );
        $get_items_sql = $this->nbtwccs_prepare("SELECT order_item_id,order_item_type FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d ", $data_sql);
        $line_items = $wpdb->get_results($get_items_sql, ARRAY_N);
        if (!empty($line_items) AND is_array($line_items)) {
            foreach ($line_items as $v) {
                $order_item_id = $v[0];
                $order_item_type = $v[1];

                switch ($order_item_type) {
                    case 'line_item':

                        $amount = wc_get_order_item_meta($order_item_id, '_line_subtotal', true);
                        wc_update_order_item_meta($order_item_id, '_line_subtotal', $this->back_convert($amount, $_nbtwccs_order_rate, $decimals));

                        $amount = wc_get_order_item_meta($order_item_id, '_line_total', true);
                        wc_update_order_item_meta($order_item_id, '_line_total', $this->back_convert($amount, $_nbtwccs_order_rate, $decimals));

                        $amount = wc_get_order_item_meta($order_item_id, '_line_subtotal_tax', true);
                        wc_update_order_item_meta($order_item_id, '_line_subtotal_tax', $this->back_convert($amount, $_nbtwccs_order_rate, $decimals));

                        $amount = wc_get_order_item_meta($order_item_id, '_line_tax', true);
                        wc_update_order_item_meta($order_item_id, '_line_tax', $this->back_convert($amount, $_nbtwccs_order_rate, $decimals));

                        $_line_tax_data = wc_get_order_item_meta($order_item_id, '_line_tax_data', true);
                        if (!empty($_line_tax_data) AND is_array($_line_tax_data)) {
                            foreach ($_line_tax_data as $key => $values) {
                                if (!empty($values)) {
                                    if (is_array($values)) {
                                        foreach ($values as $k => $value) {
                                            if (is_numeric($value)) {
                                                $_line_tax_data[$key][$k] = $this->back_convert($value, $_nbtwccs_order_rate, $decimals);
                                            }
                                        }
                                    } else {
                                        if (is_numeric($values)) {
                                            $_line_tax_data[$key] = $this->back_convert($values, $_nbtwccs_order_rate, $decimals);
                                        }
                                    }
                                }
                            }
                        }

                        wc_update_order_item_meta($order_item_id, '_line_tax_data', $_line_tax_data);

                        break;

                    case 'shipping':
                        $amount = wc_get_order_item_meta($order_item_id, 'cost', true);
                        wc_update_order_item_meta($order_item_id, 'cost', $this->back_convert($amount, $_nbtwccs_order_rate, $decimals));


                        $taxes = wc_get_order_item_meta($order_item_id, 'taxes', true);

                        if (!empty($taxes) AND is_array($taxes)) {
                            foreach ($taxes as $key => $values) {
                                if (!empty($values)) {
                                    if (is_array($values)) {
                                        foreach ($values as $k => $value) {
                                            if (is_numeric($value)) {
                                                $taxes[$key][$k] = $this->back_convert($value, $_nbtwccs_order_rate, $decimals);
                                            }
                                        }
                                    } else {
                                        if (is_numeric($values)) {
                                            $taxes[$key] = $this->back_convert($values, $_nbtwccs_order_rate, $decimals);
                                        }
                                    }
                                }
                            }
                        }

                        wc_update_order_item_meta($order_item_id, 'taxes', $taxes);

                        break;

                    case 'tax':
                        $amount = wc_get_order_item_meta($order_item_id, 'tax_amount', true);
                        wc_update_order_item_meta($order_item_id, 'tax_amount', $this->back_convert($amount, $_nbtwccs_order_rate, 3));

                        $amount = wc_get_order_item_meta($order_item_id, 'shipping_tax_amount', true);
                        wc_update_order_item_meta($order_item_id, 'shipping_tax_amount', $this->back_convert($amount, $_nbtwccs_order_rate, $decimals));

                        break;

                    default:
                        break;
                }
            }
        }

        $order = new WC_Order($order_id);
        $refunds = $order->get_refunds();

        if (!empty($refunds)) {
            foreach ($refunds as $refund) {
                $post_id = 0;

                if (method_exists($refund, 'get_id')) {
                    $post_id = $refund->get_id();
                } else {
                    $post_id = $refund->id;
                }

                $amount = get_post_meta($post_id, '_refund_amount', true);
                update_post_meta($post_id, '_refund_amount', $this->back_convert($amount, $_nbtwccs_order_rate, $decimals));
                $amount = get_post_meta($post_id, '_order_total', true);
                update_post_meta($post_id, '_order_total', $this->back_convert($amount, $_nbtwccs_order_rate, $decimals));
                update_post_meta($post_id, '_order_currency', $this->default_currency);
            }
        }
    }

//ajax
    public function nbtwccs_recalculate_order_data() {
        if (!current_user_can('manage_options')) {
            return;
        }

        $this->recalculate_order((int) $_REQUEST['order_id']);
        wp_die('done');
    }

//***************** BEGIN ADDITIONAL INFO HTML ON THE CHECKOUT+CART ***************
//only attach some info in html
//wp-content\plugins\woocommerce\templates\cart\cart.php
    public function woocommerce_cart_item_price($product_price, $cart_item, $cart_item_key) {
        $user_currency = $this->get_currency_by_country($this->storage->get_val('nbtwccs_user_country'));
        $currencies = $this->get_currencies();

        if ($user_currency != $this->current_currency AND ! empty($user_currency)) {
            $tmp_curr_currency = $this->current_currency;
            $this->set_currency($user_currency);


            $back_convert = true;
            if ($user_currency == $this->default_currency) {
                $back_convert = false;
            }
            if ($this->is_multiple_allowed) {
                $back_convert = true;
            }
            if (!$this->is_multiple_allowed AND ( $user_currency !== $this->default_currency)) {
                $back_convert = false;
            }

            $_price = $cart_item['line_total'];
            
            if ('incl' === WC()->cart->tax_display_cart) {
                $_price = $cart_item['line_total'] + $cart_item['line_tax'];
            }

            if ($back_convert) {
                $cart_price = $this->back_convert($_price, $currencies[$tmp_curr_currency]['rate']) / $cart_item['quantity'];
            } else {
                $cart_price = $_price / $cart_item['quantity'];
            }
            if ($this->is_fixed_enabled) {
                //$cart_price=$cart_item['data']->get_price()/$currencies[$this->current_currency]['rate'];
            }
            $wc_price = $this->wc_price($cart_price, true, array('decimals' => $this->get_currency_price_num_decimals($user_currency, $this->price_num_decimals)));
            $product_price .= $this->get_cart_item_price_html($wc_price);


            $this->set_currency($tmp_curr_currency);
        }

        return $product_price;
    }

//wp-content\plugins\woocommerce\templates\cart\cart.php
    public function woocommerce_cart_item_subtotal($product_subtotal, $cart_item, $cart_item_key) {
        $user_currency = $this->get_currency_by_country($this->storage->get_val('nbtwccs_user_country'));
        $currencies = $this->get_currencies();

        if ($user_currency != $this->current_currency AND ! empty($user_currency)) {
            $tmp_curr_currency = $this->current_currency;
            $this->set_currency($user_currency);

            $cart_amount = $cart_item['line_subtotal'];
            
            if ('incl' === WC()->cart->tax_display_cart) {
                $cart_amount = $cart_item['line_subtotal'] + $cart_item['line_subtotal_tax'];
            }

            $back_convert = true;
            if ($user_currency == $this->default_currency) {
                $back_convert = false;
            }
            if ($this->is_multiple_allowed) {
                $back_convert = true;
            }
            if (!$this->is_multiple_allowed AND ( $user_currency !== $this->default_currency)) {
                $back_convert = false;
            }


            if ($back_convert) {
                $cart_amount = $this->back_convert($cart_amount, $currencies[$tmp_curr_currency]['rate']);
            }
            if ($this->is_fixed_enabled) {
                //$cart_amount=($cart_item['data']->get_price()/$currencies[$this->current_currency]['rate'])*$cart_item['quantity'];
            }

            $wc_price = $this->wc_price($cart_amount, true, array('decimals' => $this->get_currency_price_num_decimals($user_currency, $this->price_num_decimals)));
            $product_subtotal .= $this->get_cart_item_price_html($wc_price);


            $this->set_currency($tmp_curr_currency);
        }

        return $product_subtotal;
    }

//wp-content\plugins\woocommerce\templates\cart\cart-totals.php
    public function woocommerce_cart_subtotal($cart_subtotal, $compound, $woo) {
        $user_currency = $this->get_currency_by_country($this->storage->get_val('nbtwccs_user_country'));
        $currencies = $this->get_currencies();

        if ($user_currency != $this->current_currency AND ! empty($user_currency)) {

            $amount = 0;
            if ($compound) {
                $amount = $woo->cart_contents_total + $woo->shipping_total + $woo->get_taxes_total(false, false);
// Otherwise we show cart items totals only (before discount)
            } else {

// Display varies depending on settings
                if ($woo->tax_display_cart == 'excl') {
                    $amount = $woo->subtotal_ex_tax;
                } else {
                    $amount = $woo->subtotal;
                }
            }
            $tmp_curr_currency = $this->current_currency;
            $this->set_currency($user_currency);


            $back_convert = true;
            if ($user_currency == $this->default_currency) {
                $back_convert = false;
            }
            if ($this->is_multiple_allowed) {
                $back_convert = true;
            }
            if (!$this->is_multiple_allowed AND ( $user_currency !== $this->default_currency)) {
                $back_convert = false;
            }


            if ($back_convert) {
                $amount = $this->back_convert($amount, $currencies[$tmp_curr_currency]['rate']);
            }

            $wc_price = $this->wc_price($amount, true, array('decimals' => $this->get_currency_price_num_decimals($user_currency, $this->price_num_decimals)));
            $cart_subtotal .= $this->get_cart_item_price_html($wc_price);


            $this->set_currency($tmp_curr_currency);
        }

        return $cart_subtotal;
    }

//wp-content\plugins\woocommerce\includes\class-wc-cart.php
    public function woocommerce_cart_total($html_value) {

        $user_currency = $this->get_currency_by_country($this->storage->get_val('nbtwccs_user_country'));
        $currencies = $this->get_currencies();


        if ($user_currency != $this->current_currency AND ! empty($user_currency)) {

            $tmp_curr_currency = $this->current_currency;
            $this->set_currency($user_currency);
            $total = WC()->cart->total;


            $back_convert = true;
            if ($user_currency == $this->default_currency) {
                $back_convert = false;
            }
            if ($this->is_multiple_allowed) {
                $back_convert = true;
            }
            if (!$this->is_multiple_allowed AND ( $user_currency !== $this->default_currency)) {
                $back_convert = false;
            }


            if ($back_convert) {
                $total = $this->back_convert($total, $currencies[$tmp_curr_currency]['rate']);
            }

            $wc_price = $this->wc_price($total, true, array('decimals' => $this->get_currency_price_num_decimals($user_currency, $this->price_num_decimals)));
            $html_value .= $this->get_cart_item_price_html($wc_price);

            $this->set_currency($tmp_curr_currency);
        }

        return $html_value;
    }


    public function woocommerce_cart_totals_taxes_total_html($html_value) {

        $user_currency = $this->get_currency_by_country($this->storage->get_val('nbtwccs_user_country'));
        $currencies = $this->get_currencies();

        if ($user_currency != $this->current_currency AND ! empty($user_currency)) {
            $tmp_curr_currency = $this->current_currency;
            $this->set_currency($user_currency);

            $total = 0;
            $compound = true;
            foreach (WC()->cart->taxes as $key => $tax) {
                if (!$compound && WC_Tax::is_compound($key))
                    continue;
                $total += $tax;
            }
            foreach (WC()->cart->shipping_taxes as $key => $tax) {
                if (!$compound && WC_Tax::is_compound($key))
                    continue;
                $total += $tax;
            }

            $back_convert = true;
            if ($user_currency == $this->default_currency) {
                $back_convert = false;
            }
            if ($this->is_multiple_allowed) {
                $back_convert = true;
            }
            if (!$this->is_multiple_allowed AND ( $user_currency !== $this->default_currency)) {
                $back_convert = false;
            }


            if ($back_convert) {
                $total = $this->back_convert($total, $currencies[$tmp_curr_currency]['rate']);
            }

            $wc_price = $this->wc_price($total, true, array('decimals' => $this->get_currency_price_num_decimals($user_currency, $this->price_num_decimals)));
            $html_value .= $this->get_cart_item_price_html($wc_price);


            $this->set_currency($tmp_curr_currency);
        }


        return $html_value;
    }

    public function woocommerce_cart_tax_totals($tax_totals, $woo) {

        $user_currency = $this->get_currency_by_country($this->storage->get_val('nbtwccs_user_country'));
        $currencies = $this->get_currencies();

        if ($user_currency != $this->current_currency AND ! empty($user_currency)) {
            $tmp_curr_currency = $this->current_currency;
            $this->set_currency($user_currency);

            if (!empty($tax_totals)) {
                foreach ($tax_totals as $key => $o) {

                    $amount = $o->amount;
                    $back_convert = true;
                    if ($user_currency == $this->default_currency) {
                        $back_convert = false;
                    }
                    if ($this->is_multiple_allowed) {
                        $back_convert = true;
                    }
                    if (!$this->is_multiple_allowed AND ( $user_currency !== $this->default_currency)) {
                        $back_convert = false;
                    }


                    if ($back_convert) {
                        $amount = $this->back_convert($amount, $currencies[$tmp_curr_currency]['rate']);
                    }

                    $wc_price = $this->wc_price($amount, true, array('decimals' => $this->get_currency_price_num_decimals($user_currency, $this->price_num_decimals)));
                    $o->formatted_amount .= $this->get_cart_item_price_html($wc_price);
                }
            }


            $this->set_currency($tmp_curr_currency);
        }

        return $tax_totals;
    }

//wp-content\plugins\woocommerce\includes\wc-cart-functions.php
    public function woocommerce_cart_shipping_method_full_label($label, $method) {

        if ($method->cost > 0) {
            $user_currency = $this->get_currency_by_country($this->storage->get_val('nbtwccs_user_country'));
            $currencies = $this->get_currencies();

            if ($user_currency != $this->current_currency AND ! empty($user_currency)) {
                $tmp_curr_currency = $this->current_currency;
                $this->set_currency($user_currency);

                if (WC()->cart->tax_display_cart == 'excl') {
                    $amount = $method->cost;
                } else {
                    $amount = $method->cost + $method->get_shipping_tax();
                }


                $back_convert = true;
                if ($user_currency == $this->default_currency) {
                    $back_convert = false;
                }
                if ($this->is_multiple_allowed) {
                    $back_convert = true;
                }
                if (!$this->is_multiple_allowed AND ( $user_currency !== $this->default_currency)) {
                    $back_convert = false;
                }

                if ($back_convert) {
                    $amount = $this->back_convert($amount, $currencies[$tmp_curr_currency]['rate']);
                }

                $wc_price = $this->wc_price($amount, true, array('decimals' => $this->get_currency_price_num_decimals($user_currency, $this->price_num_decimals)));

                $label .= $this->get_cart_item_price_html($wc_price);

                $this->set_currency($tmp_curr_currency);
            }
        }

        return $label;
    }

    private function get_cart_item_price_html($wc_price) {
        $html = '<div class="nbtwccs_cart_item_price">';
        $html .= apply_filters('nbtwccs_get_approximate_amount_text', sprintf(__('(Approx. %s)', 'netbase_solutions'), $wc_price), $wc_price);
        $html .= '</div>';
        return $html;
    }

//***************** END ADDITIONAL INFO HTML ON THE CHECKOUT+CART ***************
//custom code for Woocommerce Advanced Shipping by http://jeroensormani.com/ in multiple mode
    public function woocommerce_cart_get_taxes($taxes, $woo_cart) {
        if ($this->is_multiple_allowed AND $this->current_currency != $this->default_currency) {
            $currencies = $this->get_currencies();
            if (!empty($woo_cart->shipping_taxes)) {
//as it recounted twice - down it!
                foreach ($woo_cart->shipping_taxes as $key => $value) {
                    $woo_cart->shipping_taxes[$key] = $value * $currencies[$this->current_currency]['rate'];
                }
            }

            foreach (array_keys($woo_cart->taxes + $woo_cart->shipping_taxes) as $key) {
                $taxes[$key] = ( isset($woo_cart->shipping_taxes[$key]) ? $woo_cart->shipping_taxes[$key] : 0 ) + ( isset($woo_cart->taxes[$key]) ? $woo_cart->taxes[$key] : 0 );
            }
        }
        return $taxes;
    }


    public function woocommerce_after_calculate_totals($woo_cart) {
        if ($this->is_multiple_allowed AND $this->current_currency != $this->default_currency AND is_ajax()) {
            if (isset($_POST['billing_address_1'])) {
                $currencies = $this->get_currencies();
                if (!empty($woo_cart->shipping_taxes)) {
//as it recounted twice - down it!
                    foreach ($woo_cart->shipping_taxes as $key => $value) {
                        $woo_cart->shipping_taxes[$key] = $value * $currencies[$this->current_currency]['rate'];
                    }
                }

                foreach (array_keys($woo_cart->taxes + $woo_cart->shipping_taxes) as $key) {
                    $woo_cart->taxes[$key] = ( isset($woo_cart->shipping_taxes[$key]) ? $woo_cart->shipping_taxes[$key] : 0 ) + ( isset($woo_cart->taxes[$key]) ? $woo_cart->taxes[$key] : 0 );
                }



                $total = $woo_cart->total;
                $currencies = $this->get_currencies();
                if (!empty($woo_cart->shipping_taxes)) {
//as it recounted twice - down it!
                    foreach ($woo_cart->shipping_taxes as $key => $value) {
                        $total = $total - ($value / $currencies[$this->current_currency]['rate'] - $value);
                    }
                }

                $woo_cart->total = $total;
            }
        }
    }

    public function escape($value) {
        return sanitize_text_field(esc_html($value));
    }

    public function wc_get_template($located, $template_name, $args, $template_path, $default_path) {
        if (isset($args['order'])) {
            if (is_object($args['order']) AND ! is_null($args['order'])) {
                $order = $args['order'];
                
                if (substr($template_name, 0, 6) === 'emails') {
                    if (method_exists($order, 'get_currency')) {
                        $this->set_currency($order->get_currency());
                    }
                }
            }
        }

        return $located;
    }

    public function woocommerce_fix_shipping_calc($arg, $sum, $_this) {
        $rate = 1;
        if ($this->is_multiple_allowed) {
            $currencies = $this->get_currencies();
            $rate = $currencies[$this->current_currency]['rate'];
            $arg['cost'] = $arg['cost'] / $rate;
        }
        return $arg;
    }

    public function nbtwccs_fix_decimals($code) {
        global $wp_filter;
        $functions = debug_backtrace();
        foreach ($functions as $funcs) {
            if ($funcs['function'] == 'add_rate') {
                $decimal = 2;
                $decimal = $this->get_currency_price_num_decimals($this->default_currency);
                return $decimal;
            }
        }
        return $code;
    }

    //Thank you @jonathanmoorebcsorg !!!
    public function raw_sale_price_filter($price, $product = NULL) {
        return ($price == '') ? '' : $this->raw_woocommerce_price($price, $product);
    }

    function nbtwccs_woocommerce_cart_price_html($price_html, $product = null) {

        static $customer_price_format = -1;
        if ($customer_price_format === -1) {
            /*$customer_price_format = get_option('nbtwccs_customer_price_format', '__PRICE__');*/
            $customer_price_format = '__PRICE__';
        }
        $currencies = $this->get_currencies();
        if (empty($customer_price_format)) {
            $customer_price_format = '__PRICE__';
        }
        if (!empty($customer_price_format)) {
            $txt = '<span class="nbtwccs_special_price_code" >' . $customer_price_format . '</span>';
            $txt = str_replace('__PRICE__', $price_html, $txt);
            $price_html = str_replace('__CODE__', $this->current_currency, $txt);
            $price_html = apply_filters('nbtwccs_price_html_tail', $price_html);
        }
        
        return $price_html;
    }

    //notices functions
    public function init_style_notice() {
        if (is_admin()) {
            global $wp_version;
            if (version_compare($wp_version, '4.2', '>=') && (int) get_option('nbtwccs_first_activation', 0) == 1) {
                $alert = (array) get_option('nbtwccs_alert_notice', array());
                if (empty($alert['woocommerce-currency-switcher'])) {
                    
                    add_action('wp_ajax_nbtwccs_dismiss_alert', array($this, 'nbtwccs_dismiss_alert'));
                }
                
            }
        }
    }    

    function nbtwccs_dismiss_alert() {
        check_ajax_referer('nbtwccs_dissmiss_alert', 'sec');
        $alert = (array) get_option('nbtwccs_alert_notice', array());
        $alert[$_POST['alert']] = 1;

        add_option('nbtwccs_alert_notice', $alert, '', 'no');
        update_option('nbtwccs_alert_notice', $alert);

        exit;
    }

    public function nbtwccs_prepare($query, $args) {
        if (is_null($query)) {
            return;
        }
        $sql_val = array();

        $query = str_replace("'%s'", '%s', $query); // in case someone mistakenly already singlequoted it
        $query = str_replace('"%s"', '%s', $query); // doublequote unquoting
        $query = preg_replace('|(?<!%)%f|', '%F', $query); // Force floats to be locale unaware
        $query = preg_replace('|(?<!%)%s|', "'%s'", $query); // quote the strings, avoiding escaped strings like %%s
        if (!is_array($args)) {
            $args = array('val' => $args, 'type' => 'string');
        }
        foreach ($args as $item) {

            if (!is_array($item) OR ! isset($item['val'])) {
                continue;
            }
            if (!isset($item['type'])) {
                $item['type'] = 'string';
            }
            $sql_val[] = $this->nbtwccs_escape_sql($item['type'], $item['val']);
        }
        return @vsprintf($query, $sql_val);
    }

    public function nbtwccs_escape_sql($type, $value) {
        switch ($type) {
            case'string':
                global $wpdb;
                return $wpdb->_real_escape($value);
                break;
            case'int':
                return intval($value);
                break;
            case'float':
                return floatval($value);
                break;
            default :
                global $wpdb;
                return $wpdb->_real_escape($value);
        }
    }

    public function check_currency_on_checkout() {
        if (!$this->is_multiple_allowed) {
            $curr_curr = $this->default_currency;
            $this->current_currency = $curr_curr;
            $this->storage->set_val('nbtwccs_current_currency', $curr_curr);
        }
    }

    //compatibilites
    function nbtwccs_convert_price($amount, $is_cond_multi = false) {
        if (get_option('nbtwccs_is_multiple_allowed', 0) AND $is_cond_multi) {
            return $this->nbtwccs_exchange_value($amount);
        } elseif ($is_cond_multi == false) {
            return $this->nbtwccs_exchange_value($amount);
        }
        return $amount;
    }

    function nbtwccs_back_convert_price($amount, $is_cond_multi = false) {
        $currencies = $this->get_currencies();
        $curr_currency = $this->current_currency;
        if (get_option('nbtwccs_is_multiple_allowed', 0) AND $is_cond_multi) {
            return $this->back_convert($amount, $currencies[$curr_currency]['rate'], $currencies[$curr_currency]['decimals']);
        } elseif ($is_cond_multi == false) {
            return $this->back_convert($amount, $currencies[$curr_currency]['rate'], $currencies[$curr_currency]['decimals']);
        }
        return $amount;
    }

    function nbtwccs_convert_price_wcdp($amount, $is_cond_multi = false, $method) {
        if ($method != 'discount__amount') {
            return $amount;
        }
        if (get_option('nbtwccs_is_multiple_allowed', 0) AND $is_cond_multi) {
            return $this->nbtwccs_exchange_value($amount);
        } elseif ($is_cond_multi == false) {
            return $this->nbtwccs_exchange_value($amount);
        }
        return $amount;
    }

    //fix woo 3.3.0
    function woocommerce_coupon_loaded($coupon) {
        if (!$this->is_multiple_allowed OR $this->current_currency == $this->default_currency) {
            return $coupon;
        }
        $convert = false;
        $prices = array();
        $count_id = $coupon->get_id();
        $prices['amount'] = $coupon->get_amount();
        $prices['min_spend'] = $coupon->get_minimum_amount();
        $prices['max_spend'] = $coupon->get_maximum_amount();
        if (!$coupon->is_type('percent_product') AND ! $coupon->is_type('percent')) {
            $convert = true;
        }
        //convert
        foreach ($prices as $key => $val) {
            if (!('amount' == $key AND ! $convert)) {
                $prices[$key] = $this->nbtwccs_exchange_value($val);
            }
            if ($this->is_fixed_coupon) {//fixed coupon
                if ($this->fixed_coupon->is_exists($count_id, $this->current_currency, $key)) {
                    $tmp_amount = floatval($this->fixed_coupon->get_value($count_id, $this->current_currency, $key));
                    if ((int) $tmp_amount !== -1) {
                        $prices[$key] = $tmp_amount;
                    }
                }
                if ((float) $prices[$key] === 0.0) {
                    $prices[$key] == "";
                }
            }
        }
        
        $coupon->set_minimum_amount($prices['min_spend']);
        $coupon->set_maximum_amount($prices['max_spend']);
        $coupon->set_amount($prices['amount']);

        return $coupon;
    }

    //fix woo 3.3.0
    function nbtwccs_calc_tax_price($product, $price) {
        if ($product AND $product->is_taxable()) {
            return wc_get_price_to_display($product, array("qty" => 1, "price" => $price));
        } else {
            return $price;
        }
    }

    function nbtwccs_before_calculate_totals_geoip_fix() {
        if ($this->force_pay_bygeoip_rules) {
            if (isset($_SERVER['REQUEST_URI'])) {
                if (substr_count($_SERVER['REQUEST_URI'], '/checkout/')) {
                    $this->force_pay_bygeoip_rules();
                }
            }
        }
    }

    public function disable_woo_slider_script() {
        wp_dequeue_script('wc-price-slider');
    }

    public function prepare_default_currencies() {

        $default = array(
            'USD' => array(
                'name' => 'USD',
                'rate' => 1,
                'symbol' => '&#36;',
                'position' => 'right',
                'is_etalon' => 0,
                'description' => 'USA dollar',
                'hide_cents' => 0,
                'flag' => '',
            ),
        );
        $wc_currency = get_option('woocommerce_currency');

        switch ($wc_currency) {
            case 'USD':
                $default['EUR'] = array(
                    'name' => 'EUR',
                    'rate' => 0.89,
                    'symbol' => '&euro;',
                    'position' => 'left_space',
                    'is_etalon' => 0,
                    'description' => 'European Euro',
                    'hide_cents' => 0,
                    'flag' => '',
                );
                $default['USD']['is_etalon'] = 1;
                break;
            case 'EUR':
                $default['EUR'] = array(
                    'name' => 'EUR',
                    'rate' => 1,
                    'symbol' => '&euro;',
                    'position' => 'left_space',
                    'is_etalon' => 1,
                    'description' => 'European Euro',
                    'hide_cents' => 0,
                    'flag' => '',
                );
                $default['USD']['rate'] = 1.3;
                break;
            default :
                $default[$wc_currency] = array(
                    'name' => $wc_currency,
                    'rate' => 1,
                    'symbol' => $this->get_default_currency_symbol($wc_currency),
                    'position' => 'left_space',
                    'is_etalon' => 1,
                    'description' => '',
                    'hide_cents' => 0,
                    'flag' => '',
                );
                $default['USD']['rate'] = 1.25;
                $default['USD']['description'] = __('change the rate and this description to the right values', 'netbase_solutions');
                break;
        }

        return $default;
    }

    //just need it to set default data after the plugin installing
    public function get_default_currency_symbol($currency) {
        $symbols = $this->get_symbols_set();
        return isset($symbols[$currency]) ? $symbols[$currency] : '&#36;';
    }

    public function get_symbols_set() {
        return array(
            'USD' => '&#36;',
            'EUR' => '&euro;',
            'GBP' => '&pound;',
            'JPY' => '&yen;',
            'INR' => '&#8377;',
            'UAH' => 'грн.',
            'RUB' => 'руб.',
            'AED' => '&#x62f;.&#x625;',
            'AFN' => '&#x60b;',
            'ALL' => 'L',
            'AMD' => 'AMD',
            'ANG' => '&fnof;',
            'AOA' => 'Kz',
            'AWG' => 'Afl.',
            'AZN' => 'AZN',
            'BAM' => 'KM',
            'BDT' => '&#2547;&nbsp;',
            'BGN' => '&#1083;&#1074;.',
            'BHD' => '.&#x62f;.&#x628;',
            'BIF' => 'Fr',
            'BOB' => 'Bs.',
            'BTC' => '&#3647;',
            'BTN' => 'Nu.',
            'BWP' => 'P',
            'BYR' => 'Br',
            'BYN' => 'Br',
            'CDF' => 'Fr',
            'CHF' => '&#67;&#72;&#70;',
            'CNY' => '&yen;',
            'CRC' => '&#x20a1;',
            'CZK' => '&#75;&#269;',
            'DJF' => 'Fr',
            'DKK' => 'DKK',
            'DOP' => 'RD&#36;',
            'DZD' => '&#x62f;.&#x62c;',
            'EGP' => 'EGP',
            'ERN' => 'Nfk',
            'ETB' => 'Br',
            'FKP' => '&pound;',
            'GEL' => '&#x10da;',
            'GGP' => '&pound;',
            'GHS' => '&#x20b5;',
            'GIP' => '&pound;',
            'GMD' => 'D',
            'GNF' => 'Fr',
            'GTQ' => 'Q',
            'HNL' => 'L',
            'HRK' => 'Kn',
            'HTG' => 'G',
            'HUF' => '&#70;&#116;',
            'IDR' => 'Rp',
            'ILS' => '&#8362;',
            'IMP' => '&pound;',
            'IQD' => '&#x639;.&#x62f;',
            'IRR' => '&#xfdfc;',
            'IRT' => '&#x062A;&#x0648;&#x0645;&#x0627;&#x0646;',
            'ISK' => 'kr.',
            'JEP' => '&pound;',
            'JOD' => '&#x62f;.&#x627;',
            'KES' => 'KSh',
            'KGS' => '&#x441;&#x43e;&#x43c;',
            'KHR' => '&#x17db;',
            'KMF' => 'Fr',
            'KPW' => '&#x20a9;',
            'KRW' => '&#8361;',
            'KWD' => '&#x62f;.&#x643;',
            'KZT' => 'KZT',
            'LAK' => '&#8365;',
            'LBP' => '&#x644;.&#x644;',
            'LKR' => '&#xdbb;&#xdd4;',
            'LSL' => 'L',
            'LYD' => '&#x644;.&#x62f;',
            'MAD' => '&#x62f;.&#x645;.',
            'MDL' => 'MDL',
            'MGA' => 'Ar',
            'MKD' => '&#x434;&#x435;&#x43d;',
            'MMK' => 'Ks',
            'MNT' => '&#x20ae;',
            'MOP' => 'P',
            'MRO' => 'UM',
            'MUR' => '&#x20a8;',
            'MVR' => '.&#x783;',
            'MWK' => 'MK',
            'MYR' => '&#82;&#77;',
            'MZN' => 'MT',
            'NGN' => '&#8358;',
            'NIO' => 'C&#36;',
            'NOK' => '&#107;&#114;',
            'NPR' => '&#8360;',
            'OMR' => '&#x631;.&#x639;.',
            'PAB' => 'B/.',
            'PEN' => 'S/.',
            'PGK' => 'K',
            'PHP' => '&#8369;',
            'PKR' => '&#8360;',
            'PLN' => '&#122;&#322;',
            'PRB' => '&#x440;.',
            'PYG' => '&#8370;',
            'QAR' => '&#x631;.&#x642;',
            'RMB' => '&yen;',
            'RON' => 'lei',
            'RSD' => '&#x434;&#x438;&#x43d;.',
            'RWF' => 'Fr',
            'SAR' => '&#x631;.&#x633;',
            'SCR' => '&#x20a8;',
            'SDG' => '&#x62c;.&#x633;.',
            'SEK' => '&#107;&#114;',
            'SHP' => '&pound;',
            'SLL' => 'Le',
            'SOS' => 'Sh',
            'SSP' => '&pound;',
            'STD' => 'Db',
            'SYP' => '&#x644;.&#x633;',
            'SZL' => 'L',
            'THB' => '&#3647;',
            'TJS' => '&#x405;&#x41c;',
            'TMT' => 'm',
            'TND' => '&#x62f;.&#x62a;',
            'TOP' => 'T&#36;',
            'TRY' => '&#8378;',
            'TWD' => '&#78;&#84;&#36;',
            'TZS' => 'Sh',
            'UGX' => 'UGX',
            'UZS' => 'UZS',
            'VEF' => 'Bs F',
            'VND' => '&#8363;',
            'VUV' => 'Vt',
            'WST' => 'T',
            'XAF' => 'CFA',
            'XOF' => 'CFA',
            'XPF' => 'Fr',
            'YER' => '&#xfdfc;',
            'ZAR' => '&#82;',
            'ZMW' => 'ZK',
        );
    }

    public function woocommerce_admin_order_preview_line_items($items, $order) {
        if ($this->is_multiple_allowed) {
            $order_currency = get_post_meta($order->get_id(), '_order_currency', true);
            if ($order_currency AND $this->current_currency != $order_currency) {
                $this->set_currency($order_currency);
            }
        } else {
            $this->set_currency($this->default_currency);
        }

        return $items;
    }

}
$nbt_wc_cs = new NBTWCCS();
$GLOBALS['NBTWCCS'] = $nbt_wc_cs;