/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */
package org.apache.poi.hssf.eventusermodel;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.hssf.record.CellValueRecordInterface;
import org.apache.poi.hssf.record.ExtendedFormatRecord;
import org.apache.poi.hssf.record.FormatRecord;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.NumberRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
import org.apache.poi.util.LocaleUtil;

import static org.apache.logging.log4j.util.Unbox.box;

/**
 * A proxy HSSFListener that keeps track of the document formatting records, and
 * provides an easy way to look up the format strings used by cells from their
 * ids.
 */
public class FormatTrackingHSSFListener implements HSSFListener {
	private static final Logger LOG = LogManager.getLogger(FormatTrackingHSSFListener.class);
	private final HSSFListener _childListener;
	private final HSSFDataFormatter _formatter;
	private final NumberFormat _defaultFormat;
	private final Map<Integer, FormatRecord> _customFormatRecords = new HashMap<>();
	private final List<ExtendedFormatRecord> _xfRecords = new ArrayList<>();

	/**
	 * Creates a format tracking wrapper around the given listener, using
	 * the {@link Locale#getDefault() default locale} for the formats.
	 *
	 * @param childListener the listener to be wrapped
	 */
	public FormatTrackingHSSFListener(HSSFListener childListener) {
		this(childListener, LocaleUtil.getUserLocale());
	}

	/**
	 * Creates a format tracking wrapper around the given listener, using
	 * the given locale for the formats.
     *
     * @param childListener the listener to be wrapped
     * @param locale the locale for the formats
	 */
	public FormatTrackingHSSFListener(
			HSSFListener childListener, Locale locale) {
		_childListener = childListener;
		_formatter = new HSSFDataFormatter(locale);
		_defaultFormat = NumberFormat.getInstance(locale);
	}

	protected int getNumberOfCustomFormats() {
		return _customFormatRecords.size();
	}

	protected int getNumberOfExtendedFormats() {
		return _xfRecords.size();
	}

	/**
	 * Process this record ourselves, and then pass it on to our child listener
	 */
	@Override
    public void processRecord(Record record) {
		// Handle it ourselves
		processRecordInternally(record);

		// Now pass on to our child
		_childListener.processRecord(record);
	}

	/**
	 * Process the record ourselves, but do not pass it on to the child
	 * Listener.
	 *
	 * @param record the record to be processed
	 */
	public void processRecordInternally(Record record) {
		if (record instanceof FormatRecord) {
			FormatRecord fr = (FormatRecord) record;
			_customFormatRecords.put(Integer.valueOf(fr.getIndexCode()), fr);
		}
		if (record instanceof ExtendedFormatRecord) {
			ExtendedFormatRecord xr = (ExtendedFormatRecord) record;
			_xfRecords.add(xr);
		}
	}

	/**
	 * Formats the given numeric of date cells contents as a String, in as
	 * close as we can to the way that Excel would do so. Uses the various
	 * format records to manage this.
	 *
	 * TODO - move this to a central class in such a way that hssf.usermodel can
	 * make use of it too
	 *
	 * @param cell the cell
	 *
	 * @return the given numeric of date cells contents as a String
	 */
	public String formatNumberDateCell(CellValueRecordInterface cell) {
		double value;
		if (cell instanceof NumberRecord) {
			value = ((NumberRecord) cell).getValue();
		} else if (cell instanceof FormulaRecord) {
			value = ((FormulaRecord) cell).getValue();
		} else {
			throw new IllegalArgumentException("Unsupported CellValue Record passed in " + cell);
		}

		// Get the built in format, if there is one
		int formatIndex = getFormatIndex(cell);
		String formatString = getFormatString(cell);

		if (formatString == null) {
			return _defaultFormat.format(value);
		}
		// Format, using the nice new
		// HSSFDataFormatter to do the work for us
		return _formatter.formatRawCellContents(value, formatIndex, formatString);
	}

	/**
	 * Returns the format string, eg $##.##, for the given number format index.
	 *
	 * @param formatIndex the format index
	 *
	 * @return the format string
	 */
	public String getFormatString(int formatIndex) {
		String format = null;
		if (formatIndex >= HSSFDataFormat.getNumberOfBuiltinBuiltinFormats()) {
			FormatRecord tfr = _customFormatRecords.get(Integer.valueOf(formatIndex));
			if (tfr == null) {
				LOG.atError().log("Requested format at index {}, but it wasn't found", box(formatIndex));
			} else {
				format = tfr.getFormatString();
			}
		} else {
			format = HSSFDataFormat.getBuiltinFormat((short) formatIndex);
		}
		return format;
	}

	/**
	 * Returns the format string, eg $##.##, used by your cell
	 *
	 * @param cell the cell
	 *
	 * @return the format string
	 */
	public String getFormatString(CellValueRecordInterface cell) {
		int formatIndex = getFormatIndex(cell);
		if (formatIndex == -1) {
			// Not found
			return null;
		}
		return getFormatString(formatIndex);
	}

	/**
	 * Returns the index of the format string, used by your cell, or -1 if none found
	 *
	 * @param cell the cell
	 *
	 * @return the index of the format string
	 */
	public int getFormatIndex(CellValueRecordInterface cell) {
		ExtendedFormatRecord xfr = _xfRecords.get(cell.getXFIndex());
		if (xfr == null) {
			LOG.atError().log("Cell {},{} uses XF with index {}, but we don't have that", box(cell.getRow()),box(cell.getColumn()),box(cell.getXFIndex()));
			return -1;
		}
		return xfr.getFormatIndex();
	}
}
