package com.apobates.forum.utils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.IntStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * java.text.ChoiceFormat封闭的类
 * @author xiaofanku
 * @since 20190406
 */
public class DoubleBeanFormatter {
	//不可变
	private final List<CommonDoubleBean> source;
	private final static Logger logger = LoggerFactory.getLogger(DoubleBeanFormatter.class);
	
	public DoubleBeanFormatter(List<CommonDoubleBean> source) {
		List<CommonDoubleBean> sortSource = new ArrayList<>();
		sortSource.addAll(source);
		sortSource.sort(new Comparator<CommonDoubleBean>() {
			@Override
			public int compare(CommonDoubleBean o1, CommonDoubleBean o2) {
				return Double.compare(o1.getId() , o2.getId());
			}
		});
		this.source = Collections.unmodifiableList(sortSource);
	}
	
	/**
	 * 使用java.util.stream.IntStream的方式来查找索引
	 * 
	 * @param value
	 * @return
	 */
	public String format(double value) {
		if(null == source || source.isEmpty()){
			return "-";
		}
		int maxIndex = source.size();
		int index = IntStream.range(0, maxIndex).filter(i -> source.get(i).getValue() >= value).findAny().orElse(-1);
		logger.info("[format]look up index: "+index);
		
		if(index == -1) {
			//可能大于上限值
			index = maxIndex - 1;
		}
		//介于中间值
		if(source.get(index).getValue() > value && index > 0) {
			index -= 1;
		}
		return source.get(index).getTitle();
	}
	
	/**
	 * 使用java.text.ChoiceFormat类的代码查找索引
	 * 
	 * @param value
	 * @return
	 */
	public String getTitle(double value) {
		double[] data = source.stream().map(CommonDoubleBean::getValue).mapToDouble(Double::doubleValue).toArray();
		int indexOfData = lookIndex(value, data);
		logger.info("[getTitle]look up index: "+indexOfData);
		return source.get(indexOfData).getTitle();
	}
	
	//代码来自: StringBuffer ChoiceFormat.format(double number, StringBuffer toAppendTo,FieldPosition status);
	private int lookIndex(double number, double[] limits) {
		int i;
		for (i = 0; i < limits.length; ++i) {
			if (!(number >= limits[i])) {
				// same as number < choiceLimits, except catchs NaN
				break;
			}
		}
		--i;
		if (i < 0) {
			i = 0;
		}
		// return either a formatted number, or a string
		return i;
	}
}
