<?php
class WoofilterProViewWpf extends WoofiltersViewWpf {
	public $lineRatingStyle = array(
		'leer' => '.wpfStarsRatingLine{color: #eee;}',
		'leerHover' => '.wpfLineStarsRating .wpfStarItem:hover ~ .wpfStarItem{color: #eee;}',
		'fillHover' => '.wpfLineStarsRating .wpfStarsRatingLine:hover,
			.wpfStarInput:nth-of-type(1):checked ~ .active:nth-of-type(1),
			.wpfStarInput:nth-of-type(2):checked ~ .active:nth-of-type(-n+2),
			.wpfStarInput:nth-of-type(3):checked ~ .active:nth-of-type(-n+3),
			.wpfStarInput:nth-of-type(4):checked ~ .active:nth-of-type(-n+4),
			.wpfStarInput:nth-of-type(5):checked ~ .active:nth-of-type(-n+5){
			color: #eeee22; };'
		);

	private $_taxonomyList = array();


	/**
	 * Decimals custom range option value for range price filter.
	 *
	 * @var int
	 */
	public $customDecimalsRange;

	public function generatePriceFilterHtml( $filter, $filterSettings, $blockStyle, $key = 1, $viewId = '' ) {

		$settings = $this->getFilterSetting($filter, 'settings', array());
		$skin = $this->getFilterSetting($settings, 'f_skin_type');

		if ('default' == $skin) {
			return parent::generatePriceFilterHtml($filter, $filterSettings, $blockStyle);
		}

		$dataStep = $this->getFilterSetting($settings, 'f_skin_step', 1, true);
		if ($dataStep <= 0) {
			$dataStep = 1;
		}

		if (class_exists('frameWcu')) {
			$currencySwitcher = frameWcu::_()->getModule('currency');
			if (isset($currencySwitcher)) {
				$currentCurrency = $currencySwitcher->getCurrentCurrency();
				$cryptoCurrencyList = $currencySwitcher->getCryptoCurrencyList();
				if (array_key_exists($currentCurrency, $cryptoCurrencyList)) {
					$dataStep = '0.001';
				}
			}
		}
		$punkt = strpos($dataStep, '.');
		$decimal = ( false === $punkt ? 0 : strlen($dataStep) - 1 - $punkt );

		$prices = $this->wpfGetFilteredPrice();

		$settings['minPrice'] = $prices->wpfMinPrice;
		$settings['maxPrice'] = $prices->wpfMaxPrice;
		$settings['minValue'] = ReqWpf::getVar('min_price');
		$settings['maxValue'] = ReqWpf::getVar('max_price');

		$hideInputs = ( $this->getFilterSetting($settings, 'f_show_inputs') ? '' : ' wpfHidden' );

		$noActive = $settings['minValue'] && $settings['maxValue'] ? '' : 'wpfNotActive';
		$html = '<div id="' . self::$blockId . '" class="wpfFilterWrapper ' . $noActive . '" data-filter-type="' . $filter['id'] . '" data-price-skin="' . $skin .
			'" data-get-attribute="min_price,max_price" data-decimal="' . $decimal . '" data-step="' . $dataStep . '" data-minvalue="' . $prices->wpfMinPrice . '" data-maxvalue="' . $prices->wpfMaxPrice .
			'" data-slug="' . esc_attr__('price', 'woo-product-filter') . '"' . $this->getFilterSetting($filter, 'blockAttributes') . '>' .
			$this->generateFilterHeaderHtml($filter, $filterSettings) .
			$this->generateDescriptionHtml($filter) .
			'<style>' . $this->getFilterSetting($settings, 'f_skin_css') . '</style>' .
						'<input type="text" class="ion-range-slider wpfHidden passiveFilter" value=""
							data-skin="' . $skin . '"
							data-step="' . $dataStep . '"
							data-type="double"
							data-hide-from-to="' . ( $this->getFilterSetting($settings, 'f_skin_labels_fromto') == '1' ? 'false' : 'true' ) . '" 
							data-hide-min-max="' . ( $this->getFilterSetting($settings, 'f_skin_labels_minmax') == '1' ? 'false' : 'true' ) . '" 
							data-min="' . $prices->wpfMinPrice . '"
							data-max="' . $prices->wpfMaxPrice . '"' .
							( $settings['minValue'] ? ' data-from="' . $settings['minValue'] . '"' : '' ) .
							( $settings['maxValue'] ? ' data-to="' . $settings['maxValue'] . '"' : '' ) .
							' data-grid="' . ( $this->getFilterSetting($settings, 'f_skin_grid') == '1' ? 'true' : 'false' ) . '"
						/>' . $this->generatePriceInputsHtml($settings) .
			'</div></div>';
		return $html;
	}

	public function generateSearchTextFilterHtml( $filter, $filterSettings, $blockStyle, $key = 1, $viewId = '' ) {
		$settings = $this->getFilterSetting($filter, 'settings', array());
		$fullWord = $this->getFilterSetting($settings, 'f_search_only_by_full_word', 0);
		$useTitleAsPlaceholder = $this->getFilterSetting($settings, 'f_title_as_placeholder', 0);
		$excludedItems = !empty($settings['f_mlist[]']) ? explode(',', $settings['f_mlist[]']) : false;
		$name = $this->getFilterSetting($settings, 'f_search_by', '');
		$fields = array();
		$logic = $this->getFilterSetting($settings, 'f_query_logic', 'or');
		$variables = array('title' => 't', 'content' => 'c', 'excerpt' => 'e', 'attributes' => 'a');
		switch ($name) {
			case 'title':
				$fields['title'] = $variables['title'];
				break;
			case 'content':
				$fields['content'] = $variables['content'];
				break;
			case 'excerpt':
				$fields['excerpt'] = $variables['excerpt'];
				break;
			case 'coe':
				$fields['content'] = $variables['content'];
				$fields['excerpt'] = $variables['excerpt'];
				break;
			case 'toc':
				$fields['title'] = $variables['title'];
				$fields['content'] = $variables['content'];
				break;
			case 'tac':
				$fields['title'] = $variables['title'];
				$fields['content'] = $variables['content'];
				$logic = 'and';
				break;
			default:
				foreach ($variables as $field => $key) {
					if ($this->getFilterSetting($settings, 'f_search_by_' . $field, false)) {
						$fields[$field] = $key;
					}
				}
				break;
		}
		if (count($fields) == 0) {
			$fields['title'] = $variables['title'];
		}
		if (count($fields) == 1) {
			$logic = 'or';
		}
		$autocomplete = count($fields) == 1 && isset($fields['title']) ? $this->getFilterSetting($settings, 'f_search_autocomplete') : 0;

		$filterName = 'pr_search_';
		foreach ($fields as $field => $key) {
			$filterName .= $key;
		}
		$filterName .= ( 'or' == $logic ? 'o' : 'i' );
		$filterName .= ( $fullWord ? 'w' : 'l' );

		$ratingSelected = ReqWpf::getVar($filterName);

		$text = ReqWpf::getVar($filterName);

		$placeholder = $useTitleAsPlaceholder ? $settings['f_title'] : esc_attr__('Search text', 'woo-product-filter');
		$placeholderClass = $useTitleAsPlaceholder ? ' usePlaceholder' : '';

		$wrapperStart = '';
		$wrapperEnd = '';
		$htmlOpt = '<div class="wpfSingleInputSearch">
						<input name="textFilter" class="passiveFilter' . $placeholderClass . '" placeholder="' . esc_attr($placeholder) . '" type="text" value="' . esc_attr($text) . '"> <button></button>
					</div>';

		$noActive = $text ? '' : 'wpfNotActive';

		$html = '<div id="' . self::$blockId . '" class="wpfFilterWrapper ' . $noActive . '" data-filter-type="' . $filter['id'] .
			'" data-display-type="text" data-get-attribute="' . $filterName . '" data-autocomplete="' . $autocomplete .
			'" data-excluded="' . htmlspecialchars(json_encode($excludedItems), ENT_QUOTES, 'UTF-8') . '" data-slug="' . esc_attr__('text', 'woo-product-filter') .
			'"' . $this->getFilterSetting($filter, 'blockAttributes') . '>';
		$html .= $this->generateFilterHeaderHtml($filter, $filterSettings);
		$html .= $this->generateDescriptionHtml($filter);
		$html .= '<div class="wpfCheckboxHier">';
		$html .= $wrapperStart;
		$html .= $htmlOpt;
		$html .= $wrapperEnd;
		$html .= '</div>';
		$html .= '</div>';
		$html .= '</div>';

		return $html;
	}

	public function generateRatingFilterHtml( $filter, $filterSettings, $blockStyle, $key = 1, $viewId = '' ) {
		$settings = $this->getFilterSetting($filter, 'settings', array());
		$type = $this->getFilterSetting($settings, 'f_frontend_type');

		if ( 'linestars' != $type && 'liststars' != $type ) {
			return parent::generateRatingFilterHtml($filter, $filterSettings, $blockStyle);
		}

		$filterName = 'pr_rating';
		$ratingSelected = ReqWpf::getVar($filterName);

		$line = ( 'linestars' == $type );
		$size = $this->getFilterSetting($settings, 'f_stars_icon_size', 20, true);
		$activColor = $this->getFilterSetting($settings, 'f_stars_icon_color');
		$leerColor = $this->getFilterSetting($settings, 'f_stars_leer_color');
		$borderColor = $this->getFilterSetting($settings, 'f_stars_icon_border');
		$addText = $this->getFilterSetting($settings, 'f_add_text', esc_attr__('and up', 'woo-product-filter'));
		$addText5 = $this->getFilterSetting($settings, 'f_add_text5', esc_attr__('5 only', 'woo-product-filter'));

		$ratingStyle = 'font-size:' . $size . 'px;line-height:' . $size . 'px;height:' . $size . 'px;';
		$starStyle = 'stroke:' . $borderColor . ';font-size:' . $size . 'px;line-height:' . $size . 'px;';
		$wrapperStart = '<div class="wpfStarsRating" data-star-color="' . esc_attr($activColor) . '" data-leer-color="' . esc_attr($leerColor) .
			'" data-display-type="' . $type . '"' . ( $line ? ' data-add-text="' . esc_attr($addText) . '" data-add-text5="' . esc_attr($addText5) . '"' : '' ) . '>';
		$wrapperEnd = '</div>';

		$htmlOpt = '';

		$this->setFilterCss('#' . self::$blockId . ' .wpfStarsRating {display:none;}');
		$this->setFilterCss('#' . self::$blockId . ' .wpfStarsRatingBlock {' . $ratingStyle . '}');
		$this->setFilterCss('#' . self::$blockId . ' .wpfRatingStar {' . $starStyle . '}');

		if ($line) {
			$htmlOpt = '<style type="text/css">' .
				str_replace('#eee', $leerColor, $this->lineRatingStyle['leer']) .
				str_replace('#eee', $leerColor, $this->lineRatingStyle['leerHover']) .
				str_replace('#eeee22', $activColor, $this->lineRatingStyle['fillHover']) .
				'</style><div class="wpfStarsRatingBlock wpfLineStarsRating"><div class="wpfStarsRatingLine active">';

			$inputs = '';
			$labels = '';
			for ($i = 1; $i <= 5; $i++) {
				$value = $i . '-5';
				$inputs .= '<input type="radio" name="ratingStar" class="wpfStarInput" id="wpfLineStar' . $i . '" value="' . $value . '"' .
					( $value == $ratingSelected ? ' checked' : '' ) . ' data-label="' . ( 5 == $i ? $addText5 : $i . ' ' . $addText ) . '">';
				$labels .= '<label class="wpfStarItem active" for="wpfLineStar' . $i . '"><svg class="wpfRatingStar"><use xlink:href="#wpfStar"></use></svg></label>';
			}
			$htmlOpt .= $inputs . $labels . '</div><div class="wpfStarsAdditional">' . ( '5-5' == $ratingSelected ? $addText5 : $addText ) . '</div></div>';
		} else {
			$this->setFilterCss('#' . self::$blockId . ' .wpfStarsRatingLine {color:' . $leerColor . ';}');
			$this->setFilterCss('#' . self::$blockId . ' .wpfStarItem.checked {color:' . $activColor . ';}');
			$begin = '<div class="wpfStarsRatingBlock"><div class="wpfStarsRatingLine">';
			for ($j = 5; $j >= 1; $j--) {
				$id = 'wpfListStar' . $j;
				$value = $j . '-5';
				$checked = ( $value == $ratingSelected ? ' checked' : '' );
				$htmlOpt .= '<div class="wpfStarsRatingBlock' . ( $value == $ratingSelected ? ' wpfLineChecked' : '' ) . '">' .
					'<div class="wpfStarsRatingLine"><input type="radio" name="ratingStar" class="wpfStarInput" id="' . $id .
					'" value="' . $value . '"' . $checked . ' data-label="' . ( 5 == $j ? $addText5 : $j . ' ' . $addText ) . '">';
				for ($i = 1; $i <= 5; $i++) {
					$htmlOpt .= '<label class="wpfStarItem' . ( $i <= $j ? ' checked' : '' ) . 
						'" for="' . $id . '"><svg class="wpfRatingStar"><use xlink:href="#wpfStar"></use></svg></label>';
				}
				$htmlOpt .= '</div><div class="wpfStarsAdditional' . $checked . '">' . ( 5 == $j ? $addText5 : $addText ) . '</div></div>';
			}
		}
		$this->setFilterCss('#' . self::$blockId . ' .wpfStarDefault {display:none;}');

		$noActive = ReqWpf::getVar($filterName) ? '' : 'wpfNotActive';
		$html = '<div id="' . self::$blockId . '" class="wpfFilterWrapper ' . $noActive . '" data-filter-type="' . $filter['id'] . '" data-display-type="' . $type .
			'" data-get-attribute="' . $filterName . '" data-slug="' . esc_attr__('rating', 'woo-product-filter') . '"' .
			$this->getFilterSetting($filter, 'blockAttributes') . '>' .	$this->generateFilterHeaderHtml($filter, $filterSettings) .
			$this->generateDescriptionHtml($filter) .
			'<div class="wpfCheckboxHier">' . $wrapperStart . $htmlOpt . $wrapperEnd .
			'<svg class="wpfStarDefault" xmlns="http://www.w3.org/2000/svg">
				<symbol id="wpfStar" viewBox="0 0 26 28">
					<path d="M26 10.109c0 .281-.203.547-.406.75l-5.672 5.531 1.344 7.812c.016.109.016.203.016.313 0 .406-.187.781-.641.781a1.27 1.27 0 0 1-.625-.187L13 21.422l-7.016 3.687c-.203.109-.406.187-.625.187-.453 0-.656-.375-.656-.781 0-.109.016-.203.031-.313l1.344-7.812L.39 10.859c-.187-.203-.391-.469-.391-.75 0-.469.484-.656.875-.719l7.844-1.141 3.516-7.109c.141-.297.406-.641.766-.641s.625.344.766.641l3.516 7.109 7.844 1.141c.375.063.875.25.875.719z"></path>
				</symbol>
			</svg></div></div></div>';

		return $html;
	}
	public function getCustomTaxonomy( $slug ) {
		$module = $this->getModule();
		if (strpos($slug, $module->ctax_prefix) === 0) {
			$key = str_replace($module->ctax_prefix, '', $slug);
			foreach (get_object_taxonomies('product', 'objects') as $name => $tax) {
				if ($name == $key) {
					$attr = new stdClass();					
					$attr->attribute_name = $name;
					$attr->attribute_slug = $slug;
					$attr->attribute_label = $tax->label;
					$attr->custom_type = 'text';
					$attr->filter_name = 'filter_' . $name;
					return $attr;
				}
			}
		} else if (strpos($slug, $module->acf_prefix) === 0) {
			$key = str_replace($module->acf_prefix, '', $slug);
			$field = acf_get_field($key);
			if (!empty($field)) {
				$attr = new stdClass();	
				$attr->attribute_name = $field['name'];
				$attr->attribute_slug = $slug;
				$attr->attribute_label = $field['label'];
				$attr->custom_type = $field['type'];
				$attr->filter_name = $slug;
				return $attr;
			}
		}
		return false;
	}

	public function generateAttributeFilterHtml( $filter, $filterSettings, $blockStyle, $key = 1, $viewId = '' ) {
		$settings = $this->getFilterSetting($filter, 'settings', array());
		$type = $this->getFilterSetting($settings, 'f_frontend_type');
		$attrId = $this->getFilterSetting($settings, 'f_list', 0, false);
		if (!is_numeric($attrId)) {
			$filter['custom_taxonomy'] = $this->getCustomTaxonomy($attrId);
		}

		if (!in_array($type, array( 'colors', 'slider' ))) {
			return parent::generateAttributeFilterHtml($filter, $filterSettings, $blockStyle, $key);
		}
		if ( 'slider' === $type ) {
			return $this->generateAttributeSliderFilterHtml($filter, $filterSettings, $blockStyle, $key, $viewId);
		}
		
		list($excludeIds, $productAttr, $filterName, $attrName, $attrLabel, $filterNameSlug) = $this->getProductAttrFilterData($filter);

		if (!$productAttr) {
			return '';
		}

		$logic = FrameWpf::_()->getModule('woofilters')->getAttrFilterLogic();
		$logicSlug = $this->getFilterSetting($settings, 'f_query_logic', 'or', false, array_keys($logic['loop']));

		$show_all_atts = $this->getFilterSetting($settings, 'f_show_all_attributes', false);
		list($showedTerms, $countsTerms, $showFilter) = $this->getShowedTerms($attrName, $show_all_atts);

		// add additional slug for filter name if logic is out of standard woocmmerce filter
		if ('not_in' == $logicSlug) {
			$filterName = 'pr_' . $filterName;
			$show_all_atts = true;
		}

		$attrSelected = ReqWpf::getVar($filterName);
		if ($attrSelected) {
			$delimetrList = array_values( $logic['delimetr'] );
			foreach ( $delimetrList as $delimetr ) {
				$slugs = explode( $delimetr, $attrSelected );
				if ( count( $slugs ) > 1 ) {
					break;
				}
			}
		}
		if ( ! empty( $slugs ) ) {
			$attrSelected = $slugs;
		}

		$search = $this->getFilterSetting($settings, 'f_show_search_input', false);
		
		$layoutHor = $this->getFilterSetting($settings, 'f_colors_layout') == 'hor';
		$wrapperStart = '<div class="wpfColorsFilter"><div class="wpfColorsFilter' . ( $layoutHor ? 'Hor' : 'Ver' ) . '">';
		$wrapperEnd = '</div></div>';

		$size = $this->getFilterSetting($settings, 'f_colors_size', 16, true);
		$icon = $this->getFilterSetting($settings, 'f_colors_type', 'square', false, array('circle', 'square', 'round'));
		$showLabels = $this->getFilterSetting($settings, 'f_colors_labels', false);
		$lineHeight = $size;

		$style = 'height:' . $size . 'px; width:' . $size . 'px; max-height:' . $size . 'px; max-width:' . $size . 'px; font-size:' . round($size / 2) . 'px; ';

		if ('square' != $icon) {
			$style .= 'border-radius:' . ( ( 'circle' == $icon ) ? '50%' : '3px' ) . '; ';
		}
		$border = false;
		if ($this->getFilterSetting($settings, 'f_colors_border', false)) {
			$width = $this->getFilterSetting($settings, 'f_colors_border_width', 0, true);
			$color = $this->getFilterSetting($settings, 'f_colors_border_color');
			if ($width >= 1 && !empty($color)) {
				$width = round($width);
				$style .= 'border:' . $width . 'px solid ' . $color . '; ';
				$border = true;
				$lineHeight -= $width * 2;
			}
		}

		$style .= 'line-height:' . $lineHeight . 'px;';

		if ($layoutHor) {
			$cntProBlock = $this->getFilterSetting($settings, 'f_colors_hor_row', 0, true);
			$margin = $this->getFilterSetting($settings, 'f_colors_hor_spacing', 0, true);

			$style .= 'margin-right:' . $margin . 'px; margin-bottom:' . $margin . 'px;';
			$styleBlock = ' class="wpfColorsRow"';
			$this->setFilterCss('#' . self::$blockId . ' .wpfColorsRow {line-height:' . $size . 'px;}');
		} else {
			$cntColunms = round($this->getFilterSetting($settings, 'f_colors_ver_columns', 1, true));
			$cntProBlock = ceil(count($productAttr) / $cntColunms);
			$styleBlock = ' class="wpfColorsCol"';
			$this->setFilterCss('#' . self::$blockId . ' .wpfColorsCol {line-height:' . $size . 'px;}');
		}
		$htmlOpt = '<div' . $styleBlock . '>';

		$showCount = $this->getFilterSetting($settings, 'f_show_count', false);

		$i = 0;
		if (!empty($viewId)) {
			$viewId = '_' . $viewId;
		}

		$this->setFilterCss('#' . self::$blockId . ' label.icon {' . $style . '}');
		foreach ($productAttr as $term) {
			$id = $term->term_id;
			if ( !empty($excludeIds) && in_array($id, $excludeIds) ) {
				continue;
			}
			$label = $this->getFilterSetting($settings, 'f_colors_text_term' . $id, $term->name);
			if ($showCount) {
				$count = ( false !== $countsTerms ) ? ( isset($countsTerms[$id]) ? $countsTerms[$id] : 0 ) : ( isset($term->count) ? $term->count : '0' );
				$label .= $layoutHor ? ' (' . $count . ')' : '<span class="wpfCount">(' . $count . ')</span>';
			}
			$slug = $term->slug;
			$color = $this->getFilterSetting($settings, 'f_colors_term' . $id, '#ffffff');
			$iconStyle = $this->getFilterSetting($settings, 'f_colors_icon_term' . $id, '');

			if ( $cntProBlock > 0 && $i == $cntProBlock ) {
				$htmlOpt .= '</div><div' . $styleBlock . '>';
				$i = 0;
			}
			$i++;
			$termSlug = urldecode($slug);
			$selector = '#' . self::$blockId . ' div[data-term-slug="' . $termSlug . '"]';
			if ( !$show_all_atts && is_array($showedTerms) && ( empty($showedTerms) || !in_array($term->term_id, $showedTerms) ) ) {
				$this->setFilterCss($selector . ' {display:none;}');
			}
			$htmlOpt .= '<div data-term-slug="' . $termSlug . '">';
			if (!$layoutHor) {
				$htmlOpt .= '<div class="wpfColorsColBlock">';
			}
			$this->setFilterCss($selector . ' label.icon {background-color:' . $color . ';' . ( !$border && ( '#ffffff' == $color ) ? 'border:1px solid #cccccc;' : '' ) . ( empty($iconStyle) ? '' : $iconStyle ) . '}');

			$labelColor = $this->getFilterSetting($settings, 'f_colors_label_term' . $id, '');
			if (!empty($labelColor)) {
				$this->setFilterCss($selector . ' label.wpfAttrLabel {color:' . $labelColor . ';}');
			}

			$htmlOpt .= '<input id="filter-term' . $id . $viewId . '" type="checkbox" data-term-id="' . $id . '" data-term-slug="' . urldecode($slug) . '"' .
				( $attrSelected && in_array($slug, $attrSelected) ? ' checked' : '' ) . '>' .
				'<label class="icon"' . ( $layoutHor ? ' title="' . $label . '"' : '' ) . ' data-term-name="' . $term->name . '" for="filter-term' . $id . $viewId . '"></label>';
			if (!$layoutHor) {
				if ($showLabels) {
					$htmlOpt .= '<label class="wpfAttrLabel" for="filter-term' . $id . $viewId . '" >' . $label . '</label>';
				}
				$htmlOpt .= '</div>';
			}
			$htmlOpt .= '</div>';
		}
		$htmlOpt .= '</div>';

		$blockStyle = ( !$showFilter ? 'display:none;' : '' ) . $blockStyle;
		if (!empty($blockStyle)) {
			$this->setFilterCss('#' . self::$blockId . ' {' . $blockStyle . '}');
		}

		$noActive = ReqWpf::getVar($filterName) ? '' : 'wpfNotActive';
		$showCount = $this->getFilterSetting($settings, 'f_show_count') ? ' wpfShowCount' : '';
		$html = '<div id="' . self::$blockId . '" class="wpfFilterWrapper ' . $noActive . $showCount . '" data-filter-type="' . $filter['id'] .
			'" data-display-type="' . $type . '" data-get-attribute="' . $filterName . '" data-query-logic="' . $logicSlug .
			'" data-slug="' . esc_attr__($filterNameSlug, 'woo-product-filter') . '" data-taxonomy="' . $attrName . '" data-label="' . $attrLabel .
			'" data-show-all="' . ( (int) $show_all_atts ) . '"' . $this->getFilterSetting($filter, 'blockAttributes') . '>';
		$html .= $this->generateFilterHeaderHtml($filter, $filterSettings);
		$html .= $this->generateDescriptionHtml($filter);
		if ( $search && ( 'list' == $type ) ) {
			$html .= '<div class="wpfSearchWrapper"><input class="wpfSearchFieldsFilter" type="text" placeholder="' . esc_attr__('Search ...', 'woo-product-filter') . '"></div>';
		}
		$html .= '<div class="wpfCheckboxHier">';
		$html .= $wrapperStart . $htmlOpt . $wrapperEnd;
		$html .= '</div>';
		$html .= '</div>';
		$html .= '</div>';

		return $html;
	}
	
	public function generateAttributeSliderFilterHtml( $filter, $filterSettings, $blockStyle, $key = 1, $viewId = '' ) {
		$settings = $this->getFilterSetting($filter, 'settings', array());
		$type = $this->getFilterSetting($settings, 'f_frontend_type');
		$attrId = $this->getFilterSetting($settings, 'f_list', 0, false);
		if (!is_numeric($attrId)) {
			$filter['custom_taxonomy'] = $this->getCustomTaxonomy($attrId);
		}
		
		list($excludeIds, $productAttr, $filterName, $attrName, $attrLabel, $filterNameSlug) = $this->getProductAttrFilterData($filter);
		
		if (!$productAttr) {
			return '';
		}
		
		$logic = FrameWpf::_()->getModule('woofilters')->getAttrFilterLogic();
		$logicSlug = $this->getFilterSetting($settings, 'f_query_logic', 'or', false, array_keys($logic['loop']));
		
		$show_all_atts = $this->getFilterSetting($settings, 'f_show_all_attributes', false);
		list($showedTerms, $countsTerms, $showFilter) = $this->getShowedTerms($attrName, $show_all_atts);
		
		// add additional slug for filter name if logic is out of standard woocmmerce filter
		if ('not_in' == $logicSlug) {
			$filterName = 'pr_' . $filterName;
			$show_all_atts = true;
		}
		
		$attrSelected = ReqWpf::getVar($filterName);
		if ($attrSelected) {
			$delimetrList = array_values( $logic['delimetr'] );
			foreach ( $delimetrList as $delimetr ) {
				$slugs = explode( $delimetr, $attrSelected );
				if ( count( $slugs ) > 1 ) {
					break;
				}
			}
		}
		if ( ! empty( $slugs ) ) {
			$attrSelected = $slugs;
		}
		
		$skin = $this->getFilterSetting($settings, 'f_skin_type');
		
		$dataStep = $this->getFilterSetting($settings, 'f_skin_step', 1, true);
		if ($dataStep <= 0) {
			$dataStep = 1;
		}
		
		$punkt = strpos($dataStep, '.');
		$decimal = ( false === $punkt ? 0 : strlen($dataStep) - 1 - $punkt );
		
		$attributes = array();
		$attributeIds = array();
		foreach ($productAttr as $term) {
			$id = $term->term_id;
			if ( !empty($excludeIds) && in_array($id, $excludeIds) ) {
				continue;
			}
			$name = floatval( preg_replace('/\D/', '', $term->name) );
			if ( is_numeric($name) ) {
				$attributes[$term->slug] = $name;
				$attributeIds[$term->term_id] = $name;
			}
		}
		
		if ( empty($attributes) ) {
			return '';
		}
		
		$blockStyle = ( !$showFilter ? 'display:none;' : '' ) . $blockStyle;
		if (!empty($blockStyle)) {
			$this->setFilterCss('#' . self::$blockId . ' {' . $blockStyle . '}');
		}
		
		asort($attributes);
		asort($attributeIds);
		
		$filteredData = array();
		if ($attrSelected) {
			foreach ($attrSelected as $item) {
				if (isset($attributes[$item])) {
					array_push($filteredData, $item);
				} else {
					array_push($filteredData, null);
				}
			}
		} else {
			$filteredData = array(null, null);
		}
		$attributeKeys = array_keys($attributes);
		$settings['minAttrNum'] = min($attributes);
		$settings['maxAttrNum'] = max($attributes);
		$settings['minValue'] = array_search($filteredData[0], $attributeKeys);
		$settings['maxValue'] = array_search(end($filteredData), $attributeKeys);
		
		if ( 'default' === $skin ) {
			$settings['attributes'] = array(
				'values' => $attributes,
				'keys' => $attributeKeys,
				'ids' => $attributeIds
			);
			return $this->generateAttributeDefaultSliderFilterHtml($filter, $filterSettings, $settings, $filterName, $filterNameSlug);
		}
		
		$noActive = $settings['minValue'] && $settings['maxValue'] ? '' : 'wpfNotActive';
		$html = '<div id="' . self::$blockId . '" class="wpfFilterWrapper ' . $noActive . '" data-filter-type="' . $filter['id'] . '" data-price-skin="' . $skin .
			'" data-display-type="' . $type . '" data-get-attribute="' . $filterName . '" data-decimal="' . $decimal . '" data-step="' . $dataStep . '" data-minvalue="' . $settings['minAttrNum'] . '" data-maxvalue="' . $settings['maxAttrNum'] .
			'" data-slug="' . esc_attr__($filterNameSlug, 'woo-product-filter') . '"' . $this->getFilterSetting($filter, 'blockAttributes') . '>' .
			$this->generateFilterHeaderHtml($filter, $filterSettings) .
			$this->generateDescriptionHtml($filter) .
			'<style>' . $this->getFilterSetting($settings, 'f_skin_css') . '</style>' .
			'<input type="text" class="ion-range-slider wpfAttrNumFilterRange wpfHidden passiveFilter" value=""
							data-skin="' . $skin . '"
							data-step="' . $dataStep . '"
							data-values="' . implode(',', $attributes) . '"
							data-slugs="' . implode(',', $attributeKeys) . '"
							data-term-ids="' . implode(',', array_keys($attributeIds)) . '"
							data-type="double"
							data-hide-from-to="' . ( $this->getFilterSetting($settings, 'f_skin_labels_fromto') == '1' ? 'false' : 'true' ) . '"
							data-hide-min-max="' . ( $this->getFilterSetting($settings, 'f_skin_labels_minmax') == '1' ? 'false' : 'true' ) . '"
							data-min="' . $settings['minAttrNum'] . '"
							data-max="' . $settings['maxAttrNum'] . '"' .
			( $settings['minValue'] ? ' data-from="' . $settings['minValue'] . '"' : '' ) .
			( $settings['maxValue'] ? ' data-to="' . $settings['maxValue'] . '"' : '' ) .
			' data-grid="' . ( $this->getFilterSetting($settings, 'f_skin_grid') == '1' ? 'true' : 'false' ) . '"
						/>' . $this->generateAttrInputsHtml($settings) .
			'</div></div>';
			
		return $html;
	}
	
	public function generateAttributeDefaultSliderFilterHtml( $filter, $filterSettings, $settings, $filterName, $filterNameSlug ) {
		$type = $this->getFilterSetting($settings, 'f_frontend_type');
		$noActive = $settings['minValue'] && $settings['maxValue'] ? '' : 'wpfNotActive';
		$html = '<div class="wpfFilterWrapper ' . $noActive . '" data-filter-type="' . $filter['id'] . '" data-price-skin="default" data-get-attribute="' . $filterName .
			'" data-minvalue="' . $settings['minValue'] . '" data-maxvalue="' . $settings['maxValue'] . '" data-slug="' . esc_attr__($filterNameSlug, 'woo-product-filter') .
			'" data-display-type="' . $type . '" ' . $filter['blockAttributes'] . '>' .
			$this->generateFilterHeaderHtml($filter, $filterSettings) .
			$this->generateDescriptionHtml($filter) .
			'<div id="wpfSliderRange" class="wpfPriceFilterRange wpfAttrNumFilterRange"
				data-values="' . implode(',', $settings['attributes']['values']) . '"
				data-slugs="' . implode(',', $settings['attributes']['keys']) . '"
				data-term-ids="' . implode(',', array_keys($settings['attributes']['ids'])) . '"
			></div>' .
			$this->generateAttrInputsHtml($settings) .
			'</div>';
		$html .= '</div>';
		return $html;
	}
	
	public function getProductAttrFilterData( $filter ) {
		$settings = $this->getFilterSetting($filter, 'settings', array());
		$attrId = $this->getFilterSetting($settings, 'f_list', 0, false);
		$order = $this->getFilterSetting($settings, 'f_sort_by', 'asc');
		$excludeIds = $this->getFilterSetting($settings, 'f_exclude_terms', false);
		$includeAttsId = !empty($settings['f_mlist[]']) ? explode(',', $settings['f_mlist[]']) : false;
		$orderByInclude = !empty($filter['settings']['f_order_custom']) ? 'include' : 'name';
		$args = array(
			'parent' => 0,
			'hide_empty' => $this->getFilterSetting($settings, 'f_hide_empty', false),
			'order' => $order,
			'orderby' => $orderByInclude,
			'include' => $includeAttsId
		);
		$isCustom = !empty($filter['custom_taxonomy']);
		if ($isCustom) {
			$customTaxonomy = $filter['custom_taxonomy'];
			$attrName = $customTaxonomy->attribute_name;
			$attrSlug = $customTaxonomy->attribute_slug;
			$attrLabel = strtolower($customTaxonomy->attribute_label);
			$filterNameSlug = $attrSlug;
			$filterName = $customTaxonomy->filter_name;
		} else {
			$attrName = wc_attribute_taxonomy_name_by_id((int) $attrId);
			$attrLabel = strtolower(wc_attribute_label($attrName));
			$filterNameSlug = str_replace('pa_', '', $attrName);
			$filterName = 'filter_' . $filterNameSlug;
		}
		
		if ( false !== $includeAttsId && 'include' == $orderByInclude ) {
			$args['wpf_orderby'] = implode(',', $includeAttsId);
			add_filter('get_terms_orderby', array($this, 'wpfGetTermsOrderby'), 99, 2);
		}
		$productAttr = $isCustom ? DispatcherWpf::applyFilters('getCustomTerms', array(), $attrSlug, $args) : $this->getTaxonomyHierarchy($attrName, $args);
		remove_filter('get_terms_orderby', array($this, 'wpfGetTermsOrderby'), 99, 2);
		
		return array($excludeIds, $productAttr, $filterName, $attrName, $attrLabel, $filterNameSlug);
	}

	public function getButtonsTypeHtml( $options ) {
		if ( !isset($options['settings']) || !isset($options['terms']) ) {
			return '';
		}
		$settings = $options['settings'];
		$settings = $this->getFilterSetting($settings, 'settings', array());

		$terms = $options['terms'];
		$selected = isset($options['selected']) ? $options['selected'] : false;
		$showed = isset($options['showed']) ? $options['showed'] : false;
		$counts = isset($options['counts']) ? $options['counts'] : false;

		$excludes = isset($options['excludes']) ? $options['excludes'] : false;
		if ( false !== $excludes && !is_array($excludes) ) {
			$excludes = explode(',', $excludes);
		}

		$includes = isset($options['includes']) ? $options['includes'] : false;
		if ( false !== $includes && !is_array($includes) ) {
			$includes = explode(',', $includes);
		}

		$layout = isset($options['display']) ? $options['display'] : 0;

		$blockId = self::$blockId;
		$selector = '#' . $blockId . ' .wpfButtonsFilter';
		$style = '';

		// normal styles
		$style .= $selector . ' .wpfTermWrapper {line-height:normal;';

		$padding = $this->getFilterSetting($settings, 'f_buttons_inner_spacing', 5, true, false, true);
		$style .= 'padding:' . $padding . 'px;';

		$margin = $this->getFilterSetting($settings, 'f_buttons_outer_spacing', 5, true, false, true);
		$style .= 'margin: 0 ' . $margin . 'px ' . $margin . 'px 0;';

		$bgColor = $this->getFilterSetting($settings, 'f_buttons_bg_color', '#ffffff');
		$style .= 'background-color:' . $bgColor . ';';

		$size = $this->getFilterSetting($settings, 'f_buttons_font_size', 15, true);
		$style .= 'font-size:' . $size . 'px;';

		$color = $this->getFilterSetting($settings, 'f_buttons_font_color', '#000000');
		$style .= 'color:' . $color . ';';

		$buttonsType = $this->getFilterSetting($settings, 'f_buttons_type', 'square', false, array('circle', 'square', 'corners', 'edges'));
		$style .= 'border-radius:';
		switch ($buttonsType) {
			case 'circle':
				$style .= '50%;';
				break;
			case 'corners':
				$style .= '5px;';
				break;
			case 'edges':
				$style .= ( $padding * 2 + $size ) . 'px;';
				break;
			default:
				$style .= '0;';
				break;
		}

		$border = $this->getFilterSetting($settings, 'f_buttons_border_width', 1, true, false, true);
		$style .= 'border:' . $border . 'px solid ';

		$color = $this->getFilterSetting($settings, 'f_buttons_border_color', '#000000');
		$style .= $color . ' !important;';

		$width = $this->getFilterSetting($settings, 'f_buttons_width', '', true);
		if (!empty($width)) {
			$style .= 'width:' . $width . 'px;text-align:center;';
		}
		$height = $this->getFilterSetting($settings, 'f_buttons_height', '', true);
		if (!empty($height)) {
			$style .= 'height:' . $height . 'px;line-height:' . ( $height - $padding * 2 - $border * 2 ) . 'px;';
		}

		if ( !empty($width) || !empty($height) ) {
			$style .= 'overflow:hidden;';
		}
		$style .= '}';
		
		// checked styles
		$style .= $selector . ' .wpfTermChecked{';

		$color = $this->getFilterSetting($settings, 'f_buttons_font_color_checked', '#000000');
		$style .= 'color:' . $color . ' ;';

		$color = $this->getFilterSetting($settings, 'f_buttons_border_color_checked', '#000000');
		$style .= 'border-color:' . $color . ' !important;';

		$bgColor = $this->getFilterSetting($settings, 'f_buttons_bg_color_checked', '#ffffff');
		$style .= 'background-color:' . $bgColor . ';}';

		// wrapper styles

		$maxHeight = $this->getFilterSetting($settings, 'f_max_height', 0, true);
		if ($maxHeight > 0) {
			$style .= $selector . '{max-height:' . $maxHeight . 'px;}';
		}

		if (is_array($layout)) {        	
			if ($layout['is_ver']) {
				if ($layout['cnt'] >= 1) {
					$width = number_format(100 / $layout['cnt'], 4, '.', '');
					$style .= $selector . '>li {width:' . ( $margin > 0 ? 'calc(' . $width . '% - ' . $margin . 'px)' : $width . '%' ) . ';}';
				}
			}
		}

		$this->setFilterCss($style);

		$htmlOpt = '<ul class="wpfButtonsFilter wpfFilterVerScroll' . ( isset($options['class']) ? ' ' . $options['class'] : '' ) . '">';
		$htmlOpt .= $this->generateButtonsOptionHtml($settings, $terms, $selected, $showed, $counts, $excludes, $includes);

		$htmlOpt .= '</ul>';
		return $htmlOpt;
	}
	public function generateButtonsOptionHtml( $settings, $terms, $selected, $showed, $counts, $excludes, $includes ) {
		$showImage = $this->getFilterSetting($settings, 'f_show_images', false);
		if ($showImage) {
			$imgSize = array($this->getFilterSetting($settings, 'f_images_width', 20), $this->getFilterSetting($settings, 'f_images_height', 20));
		}
		$showCount = $this->getFilterSetting($settings, 'f_show_count', false);
		$existsSelected = is_array($selected) && !empty($selected);
		$isShowed = is_array($showed);

		$blockId = '#' . self::$blockId;
		$perButton = $this->getFilterSetting($settings, 'f_buttons_per_button', false);

		$html = '';
		foreach ($terms as $term) {
			$id = $term->term_id;
			if ( !empty($excludes) && in_array($id, $excludes) ) {
				continue;
			}
			if ( !empty($includes) && !in_array($id, $includes) ) {
				continue;
			}
			if ($perButton) {
				$bgColor = $this->getFilterSetting($settings, 'f_buttons_term' . $id, '');
				if (!empty($bgColor)) {
					$this->setFilterCss($blockId . ' .wpfTermWrapper[data-term-id="' . $id . '"] {background-color:' . $bgColor . ';}');
				}
				$bgColor = $this->getFilterSetting($settings, 'f_buttons_check_term' . $id, '');
				if (!empty($bgColor)) {
					$this->setFilterCss($blockId . ' .wpfTermChecked[data-term-id="' . $id . '"] {background-color:' . $bgColor . ';}');
				}
			}
			
			$slug = $term->slug;
			$name = $this->getFilterSetting($settings, 'f_buttons_text_term' . $id, $term->name);
			$checked = $existsSelected && ( ( in_array($slug, $selected) || in_array($id, $selected) ) );

			if ( $isShowed && ( empty($showed) || !in_array($term->term_id, $showed) ) ) {
				$this->setFilterCss($blockId . ' .wpfTermWrapper[data-term-id="' . $id . '"] {display:none;}');
			}
			$img = '';
			if ($showImage) {
				$thumbnail_id = get_term_meta($id, 'thumbnail_id', true);
				$img = wp_get_attachment_image($thumbnail_id, $imgSize, false, array('alt' => $name));
			}

			$html .= '<li class="wpfTermWrapper' . ( $checked ? ' wpfTermChecked' : '' ) . '" data-term-id="' . $id . '" data-term-slug="' . urldecode($slug) . '">';
			$html .= '<input type="checkbox"' . ( $checked ? ' checked' : '' ) . '><span class="wpfValue">' . $img . $name . '</span>';
			if ($showCount) {
				$count = ( false !== $counts ) ? ( isset($counts[$id]) ? $counts[$id] : 0 ) : ( isset($term->count) ? $term->count : '0' );
				$html .= '<span class="wpfCount">(' . $count . ')</span>';
			}
			$html .= '</li>';

			if (!empty($term->children)) {
				$html .= $this->generateButtonsOptionHtml($settings, $term->children, $selected, $showed, $counts, $excludes, $includes);
			}
		}
		return $html;
	}

	public function generatePriceRangeFilterHtml( $filter, $filterSettings, $blockStyle, $key = 1, $viewId = '' ) {
		$isCustomDecimals = $this->getFilterSetting($filter['settings'], 'f_custom_decimals', false);
		if ($isCustomDecimals) {
			$this->customDecimalsRange = $this->getFilterSetting($filter['settings'], 'f_custom_decimals_range');
		}

		if (isset($this->customDecimalsRange)) {
			if (!$this->customDecimalsRange) {
				$this->customDecimalsRange = 0;
			}
			add_filter('wc_get_price_decimals', array($this, 'addWcPriceDecimals'), 10, 1);
		}

		$html = parent::generatePriceRangeFilterHtml($filter, $filterSettings, $blockStyle, $key, $viewId);

		if (isset($this->customDecimalsRange)) {
			remove_filter( 'wc_get_price_decimals', array($this, 'addWcPriceDecimals'));
		}

		return $html;
	}

	public function getSwitchTypeHtml( $options ) {
		if ( !isset($options['settings']) || !isset($options['terms']) ) {
			return '';
		}
		$settings = $this->getFilterSetting($options['settings'], 'settings', array());

		$terms = $options['terms'];
		$selected = isset($options['selected']) ? $options['selected'] : false;
		$showed = isset($options['showed']) ? $options['showed'] : false;
		$counts = isset($options['counts']) ? $options['counts'] : false;

		$excludes = isset($options['excludes']) ? $options['excludes'] : false;
		if ( false !== $excludes && !is_array($excludes) ) {
			$excludes = explode(',', $excludes);
		}

		$includes = isset($options['includes']) ? $options['includes'] : false;
		if ( false !== $includes && !is_array($includes) ) {
			$includes = explode(',', $includes);
		}

		$layout = isset($options['display']) ? $options['display'] : 0;

		$blockId = self::$blockId;
		$selector = '#' . $blockId . ' .wpfSwitchFilter';
		$style = '';
		$label = '';
		$after = '';	

		$swithType = $this->getFilterSetting($settings, 'f_switch_type', 'round', false, array('round', 'square'));
		if ('square' == $swithType) {
			$label .= 'border-radius: 0;';
			$after .= 'border-radius: 0;';
		}
		$swithHeight = $this->getFilterSetting($settings, 'f_switch_height', 16, true);
		if (16 != $swithHeight) {
			$h = $swithHeight - 2;
			$label .= 'width:' . ( $swithHeight * 2 - 2 ) . 'px;height:' . $swithHeight . 'px;';
			$after .= 'width:' . $h . 'px;height:' . $h . 'px;';
		}

		// normal styles
		$setColor = false;
		$defColor = '#b0bec5';
		$color = $this->getFilterSetting($settings, 'f_switch_color', $defColor);
		if ($color != $defColor) {
			$label .= 'background:' . $color . ';';
			$setColor = true;
		}
		if (!empty($label)) {
			$style .= $selector . ' label.wpfSwitch {' . $label . '}';
		}
		if (!empty($after)) {
			$style .= $selector . ' label.wpfSwitch:after {' . $after . '}';
		}
		
		// checked styles
		$defColor = '#81d742';
		$color = $this->getFilterSetting($settings, 'f_switch_color_checked', $defColor);
		if ( $setColor || $color != $defColor ) {
			$style .= $selector . ' input.wpfSwitch:checked + label.wpfSwitch {background:' . $color . ';}';
		}
		
		$maxHeight = $this->getFilterSetting($settings, 'f_max_height', 0, true);
		if ($maxHeight > 0) {
			$style .= $selector . '{max-height:' . $maxHeight . 'px;}';
		}
		$this->setFilterCss($style);

		$htmlOpt = '<ul class="wpfSwitchFilter wpfFilterVerScroll' . ( isset($options['class']) ? ' ' . $options['class'] : '' ) . '">';
		$htmlOpt .= $this->generateTaxonomyOptionsHtmlFromPro($terms, $options['settings'], $selected, $excludes, '', $layout, $includes, $showed, $counts);
	
		$htmlOpt .= '</ul>';
		return $htmlOpt;
	}

	public function generateToggleSwitchHtml( $id, $checked ) {
		return '<span class="wpfToggleSwitch"><input type="checkbox" id="' . $id . '" ' . $checked . ' class="wpfSwitch"><label for="' . $id . '" class="wpfSwitch"></label></span>';
	}

	public function getTextTypeHtml( $options ) {
		if ( !isset($options['settings']) || !isset($options['terms']) ) {
			return '';
		}

		$settings = $options['settings'];
		$terms = $options['terms'];
		$selected = isset($options['selected']) ? $options['selected'] : false;
		$showed = isset($options['showed']) ? $options['showed'] : false;
		$counts = isset($options['counts']) ? $options['counts'] : false;

		$layout = isset($options['display']) ? $options['display'] : 0;

		$excludes = isset($options['excludes']) ? $options['excludes'] : false;
		if ( false !== $excludes && !is_array($excludes) ) {
			$excludes = explode(',', $excludes);
		}

		$includes = isset($options['includes']) ? $options['includes'] : false;
		if ( false !== $includes && !is_array($includes) ) {
			$includes = explode(',', $includes);
		}

		$maxHeight = $this->getFilterSetting($settings, 'f_max_height', 0, true);
		if ($maxHeight > 0) {
			$this->setFilterCss('#' . self::$blockId . ' .wpfFilterVerScroll {max-height:' . $maxHeight . 'px;}');
		}
		$htmlOpt = '<ul class="wpfTextFilter wpfFilterVerScroll ' . ( isset($options['class']) ? $options['class'] : '' ) . '">';
		$htmlOpt .= $this->generateTaxonomyOptionsHtmlFromPro($terms, $settings, $selected, $excludes, '', $layout, $includes, $showed, $counts);
		
		$htmlOpt .= '</ul>';
		return $htmlOpt;
	}

	public function generateBrandFilterHtml( $filter, $filterSettings, $blockStyle, $key = 1, $viewId = '' ) {
		$settings = $this->getFilterSetting($filter, 'settings', array());

		$hiddenBrands = $this->getFilterSetting($settings, 'f_hidden_brands', false);
		$includeBrandId = ( !empty($settings['f_mlist[]']) ) ? explode(',', $settings['f_mlist[]']) : false;
		$excludeIds = !empty($settings['f_exclude_terms']) ? $settings['f_exclude_terms'] : false;

		$order = !empty($settings['f_sort_by']) ? $settings['f_sort_by'] : 'asc';
		$orderByInclude = !empty($settings['f_order_custom']) ? 'include' : 'name';
		$args = array(
			'order' => $order,
			'orderby' => $orderByInclude,
			'parent' => 0,
			'hide_empty' => $this->getFilterSetting($settings, 'f_hide_empty', false),
			'include' => $includeBrandId
		);
		$showAllBrands = $this->getFilterSetting($settings, 'f_show_all_brands', false);
		$taxonomy = 'product_brand';
		list($showedTerms, $countsTerms, $showFilter) = $this->getShowedTerms($taxonomy, $showAllBrands);

		$productBrand = $this->getTaxonomyHierarchy($taxonomy, $args);
		if (!$productBrand) {
			return '';
		}

		$brandSelected = ReqWpf::getVar('product_brand');
		if ($brandSelected) {
			$brandSelected = explode(',', $brandSelected);
		} elseif ( $hiddenBrands && $includeBrandId ) {
			$brandSelected = $includeBrandId;
		}

		$layout = $this->getFilterLayout($settings, $filterSettings);

		$htmlOpt = $this->generateTaxonomyOptionsHtmlFromPro($productBrand, $filter, $brandSelected, $excludeIds, '', $layout, $includeBrandId, $showedTerms, $countsTerms);
		$type = $filter['settings']['f_frontend_type'];

		if ('list' === $type) {
			$maxHeight = $this->getFilterSetting($settings, 'f_max_height', 0, true);
			if ($maxHeight > 0) {
				$this->setFilterCss('#' . self::$blockId . ' .wpfFilterVerScroll {max-height:' . $maxHeight . 'px;}');
			}
			$wrapperStart = '<ul class="wpfFilterVerScroll' . $layout['class'] . '">';
			$wrapperEnd = '</ul>';
		} else if ('dropdown' === $type) {
			$wrapperStart = '<select>';
			if (!empty($filter['settings']['f_dropdown_first_option_text'])) {
				$htmlOpt = '<option value="" data-slug="">' . esc_html__($filter['settings']['f_dropdown_first_option_text'], 'woo-product-filter') . '</option>' . $htmlOpt;
			} else {
				$htmlOpt = '<option value="" data-slug="">' . esc_html__('Select all', 'woo-product-filter') . '</option>' . $htmlOpt;
			}
			$wrapperEnd = '</select>';
		} else if ('mul_dropdown' === $type) {
			$wrapperStart = '<select multiple data-placeholder="' . esc_attr($this->getFilterSetting($filter['settings'], 'f_dropdown_first_option_text', __('Select all', 'woo-product-filter'))) . '">';
			$wrapperEnd = '</select>';
		}

		$noActive = $brandSelected ? '' : 'wpfNotActive';
		$noActive = $hiddenBrands ? 'wpfHidden' : $noActive;
		$preselected = $hiddenBrands ? ' wpfPreselected' : '';

		$blockStyle = ( !$showFilter ? 'display:none;' : '' ) . $blockStyle;
		if (!empty($blockStyle)) {
			$this->setFilterCss('#' . self::$blockId . ' {' . $blockStyle . '}');
		}
		$showCount = $this->getFilterSetting($settings, 'f_show_count', false) ? ' wpfShowCount' : '';
		$html = '<div id="' . self::$blockId . '" class="wpfFilterWrapper ' . $noActive . $showCount . $preselected . '" data-filter-type="' . $filter['id'] .
			'" data-display-type="' . $type . '" data-get-attribute="product_brand" data-slug="' . esc_attr__('brand', 'woo-product-filter') .
			'" data-taxonomy="product_brand" data-show-all="' . ( (int) $showAllBrands ) . '"' . $filter['blockAttributes'] . '>';
		$html .= $this->generateFilterHeaderHtml($filter, $filterSettings);
		$html .= $this->generateDescriptionHtml($filter);
		if ( 'list' === $type && $this->getFilterSetting($settings, 'f_show_search_input', false) ) {
			$html .= '<div class="wpfSearchWrapper"><input class="wpfSearchFieldsFilter" type="text" placeholder="' . esc_attr__('Search ...', 'woo-product-filter') . '"></div>';
		}
		$html .= '<div class="wpfCheckboxHier">';
		$html .= $wrapperStart;
		$html .= $htmlOpt;
		$html .= $wrapperEnd;
		$html .= '</div>';//end wpfCheckboxHier
		$html .= '</div>';//end wpfFilterContent
		$html .= '</div>';//end wpfFilterWrapper

		return $html;
	}

	public function addEditTabFilters( $part ) {
		switch ($part) {
			case 'partEditTabFiltersRatingStars':
				$this->assign('style', $this->lineRatingStyle);
				break;

			case 'partEditTabFiltersBrand':
				$wpfBrand = array(
					'exist' => taxonomy_exists('product_brand'),
					'displays' => array()
				);
				if ($wpfBrand['exist']) {
					$brandsArgs = array(
						'orderby' => 'name',
						'order' => 'asc',
						'hide_empty' => false,
						'parent' => 0
					);

					$productBrands = get_terms( 'product_brand', $brandsArgs );
					foreach ($productBrands as $tag) {
						$wpfBrand['displays'][$tag->term_id] = $tag->name;
					}
				}
				$this->assign('wpfBrandPro', $wpfBrand);
				break;

			case 'partEditTabFiltersSearchText':
				$productItems = wc_get_products(array('limit'=>-1,'status'=>array('publish'),'orderby'=>'title','order'=>'asc','return'=>'ids'));
				if ($productItems) {
					foreach ($productItems as $product_id) {
						$this->_taxonomyList['products__' . $product_id] = get_the_title($product_id) . ' (' . esc_html__('Product', 'woo-product-filter') . ')';
					}
				}
				$args = array('order' => 'asc','orderby' => 'name','parent' => 0,'hide_empty' => true);
				$productCategory = parent::getTaxonomyHierarchy('product_cat', $args);
				if ($productCategory) {
					$this->generateTaxonomyList($productCategory);
				}
				$productTag = parent::getTaxonomyHierarchy('product_tag', $args);
				if ($productTag) {
					$this->generateTaxonomyList($productTag);
				}
				$productAttr = wc_get_attribute_taxonomies();
				if ($productAttr) {
					foreach ($productAttr as $attr) {
						$productAttrValues = parent::getTaxonomyHierarchy(wc_attribute_taxonomy_name($attr->attribute_name), $args);
						if ($productAttrValues) {
							$this->generateTaxonomyList($productAttrValues);
						}
					}
				}

				$this->assign('excludedOptions', $this->_taxonomyList);
				break;

			case 'partEditTabFiltersCustomAttribute':
				$this->assign('style', $this->lineRatingStyle);
				break;

			default:
				break;
		}
		return parent::display($part . 'Pro');
	}
	public function addEditTabDesign( $part, $settings ) {
		$this->assign('settings', $settings);
		return parent::display($part . 'Pro');
	}

	public function generateTaxonomyList( $taxonomyHierarchy, $pre = '' ) {
		if (!empty($taxonomyHierarchy)) {
			foreach ($taxonomyHierarchy as $term_id => $term) {
				$this->_taxonomyList[urldecode($term->taxonomy) . '__' . $term_id] = $pre . urldecode($term->name) . ' (' . urldecode($term->taxonomy) . ')';
				if (!empty($term->children)) {
					$this->generateTaxonomyList($term->children, $pre . '&nbsp;&nbsp;');
				}
			}
		}
	}

	public function generateLoaderLayoutHtml( $options ) {
		if ( isset($options['loader_enable']) && empty($options['loader_enable']['value']) ) {
			return '';
		}
		$this->setFilterCss('.wpfLoaderLayout {position:absolute;top:0;bottom:0;left:0;right:0;background-color: rgba(255, 255, 255, 0.9);z-index: 999;}');

		$html = '<div class="wpfLoaderLayout">';
		$color = $this->getFilterSetting($this->getFilterSetting($options, 'loader_icon_color', array()), 'value', 'black');
		$icon = $this->getFilterSetting($this->getFilterSetting($options, 'loader_icon', array()), 'value', 'default|0');

		$parts = explode('|', $icon);
		if (count($parts) == 2) {
			$iconName =	$parts[0];
			$iconNumber =	$parts[1];
		} else {
			$iconName =	'default';
			$iconNumber = '0';
		}
		$this->setFilterCss('.wpfLoaderLayout .woobewoo-filter-loader {position:absolute;z-index:9;top:50%;left:50%;margin-top:-30px;margin-left:-30px;color: ' . $color . ';}');

		if ('default' === $iconName) {
			$html .= '<div class="woobewoo-filter-loader"><i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i></div>';
		} else {
			$html .= '<div class="woobewoo-filter-loader la-' . $iconName . ' la-2x">';
			for ($i = 1; $i <= $iconNumber; $i++) {
				$html .= '<div></div>';
			}
			$html .= '</div>';
		}
		return $html . '</div>';	    
	}

	public function addHideFiltersButton( $settings ) {
		$enableButton = $this->getFilterSetting($settings, 'display_hide_button' . ( UtilsWpf::isMobile() ? '_mobile' : '' ), 'no');
		if ('no' == $enableButton) {
			return '';
		}
		$isOpen = ( 'yes_open' === $enableButton );

		$showText = $this->getFilterSetting($settings, 'hide_button_show_text', esc_attr__('SHOW FILTERS', 'woo-product-filter'));
		$hideText = $this->getFilterSetting($settings, 'hide_button_hide_text', esc_attr__('HIDE FILTERS', 'woo-product-filter'));

		$html = '<button class="wfpHideButton wfpButton wfpClickable" data-is-open="' . ( $isOpen ? 1 : 0 ) . '" data-show-text="' . esc_attr($showText) . '" data-hide-text="' . esc_attr($hideText) .
			'"><span class="wfpHideText">' . esc_html( $isOpen ? $hideText : $showText ) . '</span><i class="fa fa-chevron-' . ( $isOpen ? 'up' : 'down' ) . '"></i></button>';
		return $html;
	}

	public function controlFilterSettings( $filter ) {
		$id = $filter['id'];
		$settings = $this->getFilterSetting($filter, 'settings', array());
		$type = $this->getFilterSetting($settings, 'f_frontend_type', 'list');

		if ( ( 'list' == $type ) && $this->getFilterSetting($settings, 'f_abc_index', false) ) {
			$filter['settings']['f_sort_by'] = 'asc';
			unset($filter['settings']['f_order_custom']);
			$filter['blockAttributes'] = 'data-abc="1"';
		}

		$collapsibleList = FrameWpf::_()->getModule('woofilterpro')->getCollapsibleFiltreOptions();
		if ( ( in_array( $type, $collapsibleList ) ) && $this->getFilterSetting( $settings, 'f_multi_collapsible', false ) ) {
			$filter['blockAttributes'] = 'data-collapsible="1"';
		}
		return $filter;
	}

	public function addCustomCss( $settings, $filterId ) {
		if ($this->getFilterSetting($settings, 'disable_plugin_styles', false)) {
			return '';
		}

		$useBlockStyles = $this->getFilterSetting($settings, 'use_block_styles', false);
		$useTitleStyles = $this->getFilterSetting($settings, 'use_title_styles', false);
		$useButtonStyles = $this->getFilterSetting($settings, 'use_button_styles', false);
		if ( !$useBlockStyles && !$useTitleStyles && !$useButtonStyles ) {
			return '';
		}

		$styles = $this->getFilterSetting($settings, 'styles', array());
		if (empty($styles)) {
			return '';
		}

		$module = $this->getModule();

		$standartFonts = $module->getStandardFontsList();
		$defaultFont = $module->defaultFont;

		$stylesCss = array();
		$fonts = array();
		$wrapperSelector = '#' . $filterId;
		$important = ' !important';
		$sides = array('top', 'right', 'bottom', 'left');

		// custom blocks styles
		if ($useBlockStyles) {
			$blockSelector = $wrapperSelector . ' .wpfFilterWrapper';

			$font = $this->getFilterSetting($styles, 'block_font_family', '');
			if ( !empty($font) && $font != $defaultFont ) {
				$stylesCss[$blockSelector]['font-family'] = '"' . $font . '"';
				if (!in_array($font, $standartFonts)) {
					$fonts[str_replace(' ', '+', $font)] = $font;
				}
			}

			$weight = $this->getFilterSetting($styles, 'block_font_style', '');
			if ('n' == $weight) {
				$stylesCss[$blockSelector]['font-weight'] = 'normal' . $important;
			} else if ( 'b' == $weight || 'bi' == $weight ) {
				$stylesCss[$blockSelector]['font-weight'] = 'bold' . $important;
			}
			if ( 'i' == $weight || 'bi' == $weight ) {
				$stylesCss[$blockSelector]['font-style'] = 'italic' . $important;
				if ('i' == $weight) {
					$stylesCss[$blockSelector]['font-weight'] = 'normal' . $important;
				}
			}

			$color = $this->getFilterSetting($styles, 'block_font_color', '');
			if (!empty($color)) {
				$stylesCss[$blockSelector]['color'] = $color . $important;
			}
			$size = $this->getFilterSetting($styles, 'block_font_size', '');
			if (!empty($size)) {
				$stylesCss[$blockSelector]['font-size'] = $size . 'px' . $important;
			}

			$color = $this->getFilterSetting($styles, 'block_bg_color', '');
			if (!empty($color)) {
				$stylesCss[$blockSelector]['background-color'] = $color . $important;
			}

			$style = $this->getFilterSetting($styles, 'block_border_style', '');
			if (!empty($style)) {
				$stylesCss[$blockSelector]['border-style'] = $style . $important;
			}
			$color = $this->getFilterSetting($styles, 'block_border_color', '');
			if (!empty($color)) {
				$stylesCss[$blockSelector]['border-color'] = $color . $important;
			}
			foreach ($sides as $side) {
				$width = $this->getFilterSetting($styles, 'block_border_' . $side, '', true, false, true);
				if ('' != $width) {
					$stylesCss[$blockSelector]['border-' . $side . '-width'] = $width . 'px' . $important;
				}
			}
			foreach ($sides as $side) {
				$width = $this->getFilterSetting($styles, 'block_padding_' . $side, '', true, false, true);
				if ('' != $width) {
					$stylesCss[$blockSelector]['padding-' . $side] = $width . 'px' . $important;
				}
			}
			foreach ($sides as $side) {
				$width = $this->getFilterSetting($styles, 'block_margin_' . $side, '', true, false, true);
				if ('' != $width) {
					$stylesCss[$blockSelector]['margin-' . $side] = $width . 'px' . $important;
				}
			}
			$checkbox = $this->getFilterSetting($styles, 'block_checkbox_type', '');
			if (!empty($checkbox)) {
				$blockSelector = $wrapperSelector . ' .wpfFilterWrapper .wpfCheckbox input';
				$stylesCss[$blockSelector]['display'] = 'none' . $important;

				$blockSelector = $wrapperSelector . ' .wpfFilterWrapper .wpfCheckbox label';
				$size = $this->getFilterSetting($styles, 'block_checkbox_size', 16, true, false, true);
				if (!empty($size)) {
					$stylesCss[$blockSelector]['width'] = $size . 'px' . $important;
					$stylesCss[$blockSelector]['height'] = $size . 'px' . $important;
				}

				$blockSelector = $wrapperSelector . ' .wpfFilterWrapper .wpfCheckbox label::before';

				if ('circle' == $checkbox) {
					$stylesCss[$blockSelector]['border-radius'] = '50%' . $important;
				} else if ('square' == $checkbox) {
					$stylesCss[$blockSelector]['border-radius'] = '0' . $important;
				} else if ('round' == $checkbox) {
					$stylesCss[$blockSelector]['border-radius'] = '5px' . $important;
				}

				$color = $this->getFilterSetting($styles, 'block_checkbox_border', '');
				if (!empty($color)) {
					$stylesCss[$blockSelector]['border-color'] = $color . $important;
				}
				$color = $this->getFilterSetting($styles, 'block_checkbox_color', '');
				if (!empty($color)) {
					$stylesCss[$blockSelector]['background-color'] = $color . $important;
				}

				$blockSelector = $wrapperSelector . ' .wpfFilterWrapper .wpfCheckbox input[type="checkbox"]:checked + label::after';
				$mark = $this->getFilterSetting($styles, 'block_checkbox_mark_color', '');
				if (!empty($mark)) {
					$stylesCss[$blockSelector]['color'] = $mark . $important;
					$stylesCss[$blockSelector]['font-family'] = 'FontAwesome' . $important;
					$stylesCss[$blockSelector]['content'] = '"\f00c"' . $important;
					$stylesCss[$blockSelector]['width'] = $size . 'px' . $important;
					$stylesCss[$blockSelector]['height'] = $size . 'px' . $important;
					$stylesCss[$blockSelector]['top'] = '0px' . $important;
					$stylesCss[$blockSelector]['left'] = '0px' . $important;
					$stylesCss[$blockSelector]['text-align'] = 'center' . $important;
					$stylesCss[$blockSelector]['transform'] = 'none' . $important;
					$stylesCss[$blockSelector]['font-size'] = ( $size * 0.7 ) . 'px' . $important;
					$stylesCss[$blockSelector]['line-height'] = $size . 'px' . $important;
					$stylesCss[$blockSelector]['margin'] = '0 1px' . $important;
				}		

				$blockSelector = $wrapperSelector . ' .wpfFilterWrapper .wpfCheckbox input[type="checkbox"]:checked + label::before';
				if (!empty($mark)) {
					$stylesCss[$blockSelector]['background'] = 'none' . $important;
				}
				$color = $this->getFilterSetting($styles, 'block_checkbox_checked_color', '');
				if (!empty($color)) {
					$stylesCss[$blockSelector]['background-color'] = $color . $important;
				}	
			}
		}

		// custom title styles
		if ($useTitleStyles) {
			$blockSelector = $wrapperSelector . ' .wpfFilterTitle';

			$font = $this->getFilterSetting($styles, 'title_font_family', '');
			if ( !empty($font) && $font != $defaultFont ) {
				$stylesCss[$blockSelector]['font-family'] = '"' . $font . '"';
				if (!in_array($font, $standartFonts)) {
					$fonts[str_replace(' ', '+', $font)] = $font;
				}
			}

			$weight = $this->getFilterSetting($styles, 'title_font_style', '');
			if ('n' == $weight) {
				$stylesCss[$blockSelector]['font-weight'] = 'normal' . $important;
			} else if ( 'b' == $weight || 'bi' == $weight ) {
				$stylesCss[$blockSelector]['font-weight'] = 'bold' . $important;
			}
			if ( 'i' == $weight || 'bi' == $weight ) {
				$stylesCss[$blockSelector]['font-style'] = 'italic' . $important;
				if ('i' == $weight) {
					$stylesCss[$blockSelector]['font-weight'] = 'normal' . $important;
				}
			}

			$color = $this->getFilterSetting($styles, 'title_font_color', '');
			if (!empty($color)) {
				$stylesCss[$blockSelector]['color'] = $color . $important;
			}
			$size = $this->getFilterSetting($styles, 'title_font_size', '');
			if (!empty($size)) {
				$titleSelector = $blockSelector . ' .wfpTitle, ' . $blockSelector . ' i';
				$stylesCss[$titleSelector]['font-size'] = $size . 'px' . $important;
				$stylesCss[$titleSelector]['line-height'] = $size . 'px' . $important;
				$stylesCss[$titleSelector]['height'] = 'auto' . $important;
			}

			$color = $this->getFilterSetting($styles, 'title_bg_color', '');
			if (!empty($color)) {
				$stylesCss[$blockSelector]['background-color'] = $color . $important;
			}

			$style = $this->getFilterSetting($styles, 'title_border_style', '');
			if (!empty($style)) {
				$stylesCss[$blockSelector]['border-style'] = $style . $important;
			}
			$color = $this->getFilterSetting($styles, 'title_border_color', '');
			if (!empty($color)) {
				$stylesCss[$blockSelector]['border-color'] = $color . $important;
			}
			foreach ($sides as $side) {
				$width = $this->getFilterSetting($styles, 'title_border_' . $side, '', true, false, true);
				if ('' != $width) {
					$stylesCss[$blockSelector]['border-' . $side . '-width'] = $width . 'px' . $important;
				}
			}
			foreach ($sides as $side) {
				$width = $this->getFilterSetting($styles, 'title_padding_' . $side, '', true, false, true);
				if ('' != $width) {
					$stylesCss[$blockSelector]['padding-' . $side] = $width . 'px' . $important;
				}
			}
			foreach ($sides as $side) {
				$width = $this->getFilterSetting($styles, 'title_margin_' . $side, '', true, false, true);
				if ('' != $width) {
					$stylesCss[$blockSelector]['margin-' . $side] = $width . 'px' . $important;
				}
			}
		}

		// custom buttons styles
		if ($useButtonStyles) {
			$blockSelector = $wrapperSelector . ' .wpfFilterButtons';
			$buttonSelector = $blockSelector . ' .wpfButton';
			$buttonHover = $buttonSelector . ':hover';
			$effects = array('' => $buttonSelector, '_hover' => $buttonHover);
			$stylesCss[$buttonSelector]['overflow'] = 'hidden' . $important;

			$align = $this->getFilterSetting($styles, 'button_block_align', '', false, array('center', 'left', 'right'));
			if (!empty($align)) {
				$stylesCss[$blockSelector]['text-align'] = $align . $important;
			}

			$font = $this->getFilterSetting($styles, 'button_font_family', '');
			if ( !empty($font) && $font != $defaultFont ) {
				$stylesCss[$buttonSelector]['font-family'] = '"' . $font . '"';
				if (!in_array($font, $standartFonts)) {
					$fonts[str_replace(' ', '+', $font)] = $font;
				}
			}

			$size = $this->getFilterSetting($styles, 'button_font_size', '');
			if (!empty($size)) {
				$stylesCss[$buttonSelector]['font-size'] = $size . 'px' . $important;
				$stylesCss[$buttonSelector]['line-height'] = $size . 'px' . $important;
			}

			foreach ($effects as $effect => $selector) {
				$color = $this->getFilterSetting($styles, 'button_font_color' . $effect, '');
				if (!empty($color)) {
					$stylesCss[$selector]['color'] = $color . $important;
				}
				$weight = $this->getFilterSetting($styles, 'button_font_style' . $effect, '');
				if ('n' == $weight) {
					$stylesCss[$selector]['font-weight'] = 'normal' . $important;
				} else if ( 'b' == $weight || 'bi' == $weight ) {
					$stylesCss[$selector]['font-weight'] = 'bold' . $important;
				}
				if ( 'i' == $weight || 'bi' == $weight ) {
					$stylesCss[$selector]['font-style'] = 'italic' . $important;
					if ('i' == $weight) {
						$stylesCss[$selector]['font-weight'] = 'normal' . $important;
					}
				}
			}

			// text shadow
			$x = $this->getFilterSetting($styles, 'button_text_shadow_x', '', true, false, true);
			$y = $this->getFilterSetting($styles, 'button_text_shadow_y', '', true, false, true);
			if ( '' !== $x && '' !== $y ) {
				$value = $x . 'px ' . $y . 'px';
				$blur = $this->getFilterSetting($styles, 'button_text_shadow_blur', '', true, false, true);
				if ('' !== $blur) {
					$value .= ' ' . $blur . 'px';
				}
				$color = $this->getFilterSetting($styles, 'button_text_shadow_color', '');
				if (!empty($color)) {
					$value .= ' ' . $color;
				}
				$stylesCss[$buttonSelector]['text-shadow'] = $value . $important;
			}

			// button size
			$bWidth = $this->getFilterSetting($styles, 'button_width', '', true);
			if (!empty($bWidth)) {
				$stylesCss[$buttonSelector]['width'] = $bWidth . $this->getFilterSetting($styles, 'button_width_unit', '%') . $important;
				$stylesCss[$buttonSelector]['overflow'] = 'hidden' . $important;
			}
			$bHeight = $this->getFilterSetting($styles, 'button_height', '', true);
			if (!empty($bHeight)) {
				$stylesCss[$buttonSelector]['height'] = $bHeight . 'px' . $important;
				$stylesCss[$buttonSelector]['min-height'] = '0' . $important;
			}

			// radius coners
			$radius = $this->getFilterSetting($styles, 'button_radius', '', true, false, true);
			if ('' !== $radius) {
				$stylesCss[$buttonSelector]['border-radius'] = $radius . $this->getFilterSetting($styles, 'button_radius_unit', 'px') . $important;
			}

			foreach ($effects as $effect => $selector) {
				// borders
				$color = $this->getFilterSetting($styles, 'button_border_color' . $effect, '');
				foreach ($sides as $side) {
					$width = $this->getFilterSetting($styles, 'button_border_' . $side . $effect, '', true, false, true);
					if ('' != $width) {
						$stylesCss[$selector]['border-' . $side] = $width . 'px solid ' . $color . $important;
					}
				}

				// button shadow
				$x = $this->getFilterSetting($styles, 'button_shadow_x' . $effect, '', true, false, true);
				$y = $this->getFilterSetting($styles, 'button_shadow_y' . $effect, '', true, false, true);
				if ( '' !== $x && '' !== $y ) {
					$value = $x . 'px ' . $y . 'px';
					$blur = $this->getFilterSetting($styles, 'button_shadow_blur' . $effect, '', true, false, true);
					if ('' !== $blur) {
						$value .= ' ' . $blur . 'px';
					}
					$spread = $this->getFilterSetting($styles, 'button_shadow_spread' . $effect, '', true, false, true);
					if ('' !== $spread) {
						$value .= ' ' . $spread . 'px';
					}
					$color = $this->getFilterSetting($styles, 'button_shadow_color' . $effect, '');
					if (!empty($color)) {
						$value .= ' ' . $color;
					}
					$stylesCss[$selector]['box-shadow'] = $value . $important;
				}

				// button background
				$bgType = $this->getFilterSetting($styles, 'button_bg_type' . $effect, '');
				if (!empty($bgType)) {
					if ('unicolored' == $bgType) {
						$color = $this->getFilterSetting($styles, 'button_bg_color' . $effect, '');
						if (!empty($color)) {
							$stylesCss[$selector]['background'] = $color . $important;
						}
					} else {
						$color1 = $this->getFilterSetting($styles, 'button_bg_color1' . $effect, '');
						$color2 = $this->getFilterSetting($styles, 'button_bg_color2' . $effect, '');
						if (!empty($color1)) {
							$stylesCss[$selector]['background'] = $color1; // for Old browsers
							if (!empty($color2)) {
								switch ($bgType) {
									case 'bicolored':
										$value = 'linear-gradient( to bottom, ' . $color1 . ' 50%, ' . $color2 . ' 50% )'; 							
										break;
									case 'gradient':
										$value = 'linear-gradient( to bottom, ' . $color1 . ', ' . $color2 . ')'; 
										break;
									case 'pyramid':
										$value = 'linear-gradient( to bottom, ' . $color1 . ' 0%, ' . $color2 . ' 50%, ' . $color1 . ' 100% )'; 
										break;
									default:
										$value = '';
										break;
								}
								if (!empty($value)) {
									$stylesCss[$selector]['background'] = '-webkit-' . $value . $important;
									$stylesCss[$selector]['background'] = '-moz-' . $value . $important;
									$stylesCss[$selector]['background'] = '-o-' . $value . $important;
									$stylesCss[$selector]['background'] = $value . $important;
								}
							}
						}
					}
				}
			}

			foreach ($sides as $side) {
				$width = $this->getFilterSetting($styles, 'button_padding_' . $side, '', true, false, true);
				if ('' != $width) {
					$stylesCss[$buttonSelector]['padding-' . $side] = $width . 'px' . $important;
				}
			}
			foreach ($sides as $side) {
				$width = $this->getFilterSetting($styles, 'button_margin_' . $side, '', true, false, true);
				if ('' != $width) {
					$stylesCss[$buttonSelector]['margin-' . $side] = $width . 'px' . $important;
				}
			}
		}

		$customCSS = '';
		foreach ($fonts as $key => $value) {
			$customCSS .= '@import url("//fonts.googleapis.com/css?family=' . $key . '");';
		}

		foreach ($stylesCss as $selector => $rules) {
			$customCSS .= $selector . ' {';
			foreach ($rules as $key => $value) {
				$customCSS .= $key . ': ' . $value . ';';
			}
			$customCSS .= '} ';
		}

		return $customCSS;
	}
	
	public function generateAttrInputsHtml( $settings ) {
		$skin = $this->getFilterSetting($settings, 'f_skin_type');
		if ( !isset($settings['minValue']) || is_null($settings['minValue']) ) {
			$settings['minValue'] = $settings['minAttrNum'];
		}
		if ( !isset($settings['maxValue']) || is_null($settings['maxValue']) ) {
			$settings['maxValue'] = $settings['maxAttrNum'];
		}
		
		$priceTooltip['class'] = '';
		$priceTooltip['readonly'] = 'readonly';
		$hideInputs = ' wpfHidden';
		if ( 'default' === $skin ) {
			$hideInputs = '';
			$priceTooltip['readonly'] = '';
		}
		
		return '<div class="wpfPriceInputs' . $hideInputs . '">' .
			'<div class="input-buffer-min"></div><input ' . $priceTooltip['readonly'] . ' type="number" min="' . $settings['minAttrNum'] . '" max="' . ( $settings['maxAttrNum'] - 1 ) . '" id="wpfMinAttrNum" class="wpfAttrNumField ' . $priceTooltip['class'] . '" value="' . $settings['minValue'] . '" />' .
			'<span class="wpfFilterDelimeter"> - </span>' .
			'<div class="input-buffer-max"></div><input ' . $priceTooltip['readonly'] . ' type="number" min="' . $settings['minAttrNum'] . '" max="' . $settings['maxAttrNum'] . '" id="wpfMaxAttrNum" class="wpfAttrNumField ' . $priceTooltip['class'] . '" value="' . $settings['maxValue'] . '" /> ' .
			'<input readonly type="hidden" id="wpfDataStep" value="1" />' .
			'</div>';
	}

	/**
	 * Inject wc_get_price_decimals due to plugin settings.
	 */
	public function addWcPriceDecimals( $wcPriceNumDecimals ) {
		return $this->customDecimalsRange;
	}
}
