/*
{{IS_NOTE
	Purpose:
		
	Description:
		
	History:
		May 5, 2014, Created by henri
}}IS_NOTE

Copyright (C) 2014 Potix Corporation. All Rights Reserved.

{{IS_RIGHT
}}IS_RIGHT
*/

package org.zkoss.zssex.model.sys;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import org.zkoss.poi.ss.format.CellFormat;
import org.zkoss.poi.ss.format.CellFormatResult;
import org.zkoss.poi.ss.formula.FormulaRenderer;
import org.zkoss.poi.ss.formula.ptg.Ptg;
import org.zkoss.poi.ss.util.NumberToGeneralTextConverter;
import org.zkoss.zss.model.SBook;
import org.zkoss.zss.model.SCell;
import org.zkoss.zss.model.STableStyle;
import org.zkoss.zss.model.impl.CellImpl;
import org.zkoss.zss.model.impl.TableStyleNone;
import org.zkoss.zss.model.impl.sys.formula.ParsingBook;
import org.zkoss.zss.model.sys.formula.FormulaExpression;

/**
 * @author henri
 * @since 3.5.0
 */
public class FormatEngineEx extends org.zkoss.zss.model.impl.sys.FormatEngineImpl {
	@Override
	protected CellFormat getCellFormat(String formatStr, Locale locale) {
		if ("General".equals(formatStr)) {
			return newGeneralFormat(super.getCellFormat(formatStr, locale), locale);
		}
		return super.getCellFormat(formatStr, locale);
	}
	
	
	//ZSS-565: Support input with Swedish locale into formula
	//get Locale edit text
	@Override
	protected String getFormulaEditText(SCell cell) {
		ParsingBook parsingBook = new ParsingBook(cell.getSheet().getBook());
		//ZSS-747
		FormulaExpression fexpr = (FormulaExpression) ((CellImpl)cell).getValue(false);
		if (fexpr.hasError()) {
			return fexpr.getFormulaString();
		}
		Ptg[] tokens = fexpr.getPtgs();
		return FormulaRenderer.toFormulaEditText(parsingBook, tokens, fexpr.getFormulaString());
	}

	private CellFormat newGeneralFormat(final CellFormat inner, final Locale locale) {
		return new CellFormat("General") {
			@Override
			public CellFormatResult apply(final Object value, final int cellWidth) { //ZSS-666
				if (value instanceof Number) {
					String text = NumberToGeneralTextConverter.toGeneralText(((Number)value).doubleValue(), locale, cellWidth);
					return new CellFormatResult(true, text, null);
				} else {
					return inner.apply(value, cellWidth);
				}
			}
		};
	}
	
	//ZSS-977
	//@since 3.8.0
	private static final Map<String, STableStyle> _builtInTableStyles = new HashMap<String, STableStyle>(4);
	static {
		_builtInTableStyles.put(null, TableStyleNone.instance); 

		_builtInTableStyles.put("TableStyleLight1", TableStyleLight1.instance); 
		_builtInTableStyles.put("TableStyleLight2", TableStyleLight2.instance); 
		_builtInTableStyles.put("TableStyleLight3", TableStyleLight3.instance); 
		_builtInTableStyles.put("TableStyleLight4", TableStyleLight4.instance); 
		_builtInTableStyles.put("TableStyleLight5", TableStyleLight5.instance); 
		_builtInTableStyles.put("TableStyleLight6", TableStyleLight6.instance); 
		_builtInTableStyles.put("TableStyleLight7", TableStyleLight7.instance); 

		_builtInTableStyles.put("TableStyleLight8", TableStyleLight8.instance);
		_builtInTableStyles.put("TableStyleLight9", TableStyleLight9.instance);
		_builtInTableStyles.put("TableStyleLight10", TableStyleLight10.instance);
		_builtInTableStyles.put("TableStyleLight11", TableStyleLight11.instance);
		_builtInTableStyles.put("TableStyleLight12", TableStyleLight12.instance);
		_builtInTableStyles.put("TableStyleLight13", TableStyleLight13.instance);
		_builtInTableStyles.put("TableStyleLight14", TableStyleLight14.instance);
		
		_builtInTableStyles.put("TableStyleLight15", TableStyleLight15.instance);
		_builtInTableStyles.put("TableStyleLight16", TableStyleLight16.instance);
		_builtInTableStyles.put("TableStyleLight17", TableStyleLight17.instance);
		_builtInTableStyles.put("TableStyleLight18", TableStyleLight18.instance);
		_builtInTableStyles.put("TableStyleLight19", TableStyleLight19.instance);
		_builtInTableStyles.put("TableStyleLight20", TableStyleLight20.instance);
		_builtInTableStyles.put("TableStyleLight21", TableStyleLight21.instance);

		_builtInTableStyles.put("TableStyleMedium1", TableStyleMedium1.instance); 
		_builtInTableStyles.put("TableStyleMedium2", TableStyleMedium2.instance); 
		_builtInTableStyles.put("TableStyleMedium3", TableStyleMedium3.instance); 
		_builtInTableStyles.put("TableStyleMedium4", TableStyleMedium4.instance); 
		_builtInTableStyles.put("TableStyleMedium5", TableStyleMedium5.instance); 
		_builtInTableStyles.put("TableStyleMedium6", TableStyleMedium6.instance); 
		_builtInTableStyles.put("TableStyleMedium7", TableStyleMedium7.instance); 

		_builtInTableStyles.put("TableStyleMedium8", TableStyleMedium8.instance); 
		_builtInTableStyles.put("TableStyleMedium9", TableStyleMedium9.instance); 
		_builtInTableStyles.put("TableStyleMedium10", TableStyleMedium10.instance); 
		_builtInTableStyles.put("TableStyleMedium11", TableStyleMedium11.instance); 
		_builtInTableStyles.put("TableStyleMedium12", TableStyleMedium12.instance); 
		_builtInTableStyles.put("TableStyleMedium13", TableStyleMedium13.instance); 
		_builtInTableStyles.put("TableStyleMedium14", TableStyleMedium14.instance);
		
		_builtInTableStyles.put("TableStyleMedium15", TableStyleMedium15.instance); 
		_builtInTableStyles.put("TableStyleMedium16", TableStyleMedium16.instance); 
		_builtInTableStyles.put("TableStyleMedium17", TableStyleMedium17.instance); 
		_builtInTableStyles.put("TableStyleMedium18", TableStyleMedium18.instance); 
		_builtInTableStyles.put("TableStyleMedium19", TableStyleMedium19.instance); 
		_builtInTableStyles.put("TableStyleMedium20", TableStyleMedium20.instance); 
		_builtInTableStyles.put("TableStyleMedium21", TableStyleMedium21.instance); 

		_builtInTableStyles.put("TableStyleMedium22", TableStyleMedium22.instance); 
		_builtInTableStyles.put("TableStyleMedium23", TableStyleMedium23.instance); 
		_builtInTableStyles.put("TableStyleMedium24", TableStyleMedium24.instance); 
		_builtInTableStyles.put("TableStyleMedium25", TableStyleMedium25.instance); 
		_builtInTableStyles.put("TableStyleMedium26", TableStyleMedium26.instance); 
		_builtInTableStyles.put("TableStyleMedium27", TableStyleMedium27.instance); 
		_builtInTableStyles.put("TableStyleMedium28", TableStyleMedium28.instance); 

		_builtInTableStyles.put("TableStyleDark1", TableStyleDark1.instance);
		_builtInTableStyles.put("TableStyleDark2", TableStyleDark2.instance);
		_builtInTableStyles.put("TableStyleDark3", TableStyleDark3.instance);
		_builtInTableStyles.put("TableStyleDark4", TableStyleDark4.instance);
		_builtInTableStyles.put("TableStyleDark5", TableStyleDark5.instance);
		_builtInTableStyles.put("TableStyleDark6", TableStyleDark6.instance);
		_builtInTableStyles.put("TableStyleDark7", TableStyleDark7.instance);
		
		_builtInTableStyles.put("TableStyleDark8", TableStyleDark8.instance);
		_builtInTableStyles.put("TableStyleDark9", TableStyleDark9.instance);
		_builtInTableStyles.put("TableStyleDark10", TableStyleDark10.instance);
		_builtInTableStyles.put("TableStyleDark11", TableStyleDark11.instance);
	}
	
	//ZSS-977
	@Override
	@Deprecated
	public STableStyle getTableStyle(String name) {
		return getTableStyle(null, name);
	}
	
	//ZSS-1185
	public STableStyle getTableStyle(SBook book, String name) {
		STableStyle tableStyle = book.getTableStyle(name);
		if (tableStyle == null) {
			tableStyle = _builtInTableStyles.get(name);
		}
		if (tableStyle == null) {
			final String defaultName = book.getDefaultTableStyleName();
			if (defaultName != null) {
				tableStyle = getTableStyle0(book, defaultName);
			}
		}
		if (tableStyle == null) {
			return TableStyleMedium9.instance; //default to TableStyleMedium9.instance;
		}
		return tableStyle;
	}
	
	//ZSS-1185
	private STableStyle getTableStyle0(SBook book, String name) {
		STableStyle tableStyle = book.getTableStyle(name);
		return tableStyle == null ? _builtInTableStyles.get(name) : tableStyle;
	}
	
	//ZSS-1183
	//@since 3.9.0
	@Override
	public STableStyle getExistTableStyle(SBook book, String name) {
		STableStyle tableStyle = book.getTableStyle(name);
		if (tableStyle == null) {
			tableStyle = _builtInTableStyles.get(name);
		}
		return tableStyle;
	}
}
