/* ====================================================================
   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.record;

import org.apache.poi.hssf.record.cont.ContinuableRecord;
import org.apache.poi.hssf.record.cont.ContinuableRecordOutput;
import org.apache.poi.ss.formula.ptg.Area3DPtg;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.formula.ptg.Ref3DPtg;
import org.apache.poi.ss.formula.Formula;
import org.apache.poi.util.*;

/**
 * Title:        DEFINEDNAME Record (0x0018)<p>
 * Description:  Defines a named range within a workbook.
 */
public final class NameRecord extends ContinuableRecord {
    public final static short sid = 0x0018;
	/**Included for completeness sake, not implemented */
	public final static byte  BUILTIN_CONSOLIDATE_AREA      = 1;
	/**Included for completeness sake, not implemented */
	public final static byte  BUILTIN_AUTO_OPEN             = 2;
	/**Included for completeness sake, not implemented */
	public final static byte  BUILTIN_AUTO_CLOSE            = 3;
	/**Included for completeness sake, not implemented */
	public final static byte  BUILTIN_DATABASE              = 4;
	/**Included for completeness sake, not implemented */
	public final static byte  BUILTIN_CRITERIA              = 5;

	public final static byte  BUILTIN_PRINT_AREA            = 6;
	public final static byte  BUILTIN_PRINT_TITLE           = 7;

	/**Included for completeness sake, not implemented */
	public final static byte  BUILTIN_RECORDER              = 8;
	/**Included for completeness sake, not implemented */
	public final static byte  BUILTIN_DATA_FORM             = 9;
	/**Included for completeness sake, not implemented */
	public final static byte  BUILTIN_AUTO_ACTIVATE         = 10;
	/**Included for completeness sake, not implemented */
	public final static byte  BUILTIN_AUTO_DEACTIVATE       = 11;
	/**Included for completeness sake, not implemented */
	public final static byte  BUILTIN_SHEET_TITLE           = 12;

	public final static byte  BUILTIN_FILTER_DB             = 13;

	private static final class Option {
		public static final int OPT_HIDDEN_NAME =   0x0001;
		public static final int OPT_FUNCTION_NAME = 0x0002;
		public static final int OPT_COMMAND_NAME =  0x0004;
		public static final int OPT_MACRO =         0x0008;
		public static final int OPT_COMPLEX =       0x0010;
		public static final int OPT_BUILTIN =       0x0020;
		public static final int OPT_BINDATA =       0x1000;
		public static boolean isFormula(int optValue) {
			return (optValue & 0x0F) == 0;
		}
	}

	private short             field_1_option_flag;
	private byte              field_2_keyboard_shortcut;
	/** One-based extern index of sheet (resolved via LinkTable). Zero if this is a global name  */
	private short             field_5_externSheetIndex_plus1;
	/** the one based sheet number.  */
	private int               field_6_sheetNumber;
	private boolean           field_11_nameIsMultibyte;
	private byte              field_12_built_in_code;
	private String            field_12_name_text;
	private Formula           field_13_name_definition;
	private String            field_14_custom_menu_text;
	private String            field_15_description_text;
	private String            field_16_help_topic_text;
	private String            field_17_status_bar_text;


	/** Creates new NameRecord */
	public NameRecord() {
		field_13_name_definition = Formula.create(Ptg.EMPTY_PTG_ARRAY);

		field_12_name_text = "";
		field_14_custom_menu_text = "";
		field_15_description_text = "";
		field_16_help_topic_text = "";
		field_17_status_bar_text = "";
	}

	/**
	 * Constructor to create a built-in named region
	 * @param builtin Built-in byte representation for the name record, use the public constants
	 * @param sheetNumber the sheet which the name applies to 
	 */
	public NameRecord(byte builtin, int sheetNumber)
	{
		this();
		field_12_built_in_code = builtin;
		setOptionFlag((short)(field_1_option_flag | Option.OPT_BUILTIN));
		// the extern sheets are set through references
		field_6_sheetNumber = sheetNumber;
	}

	/** sets the option flag for the named range
	 * @param flag option flag
	 */
	public void setOptionFlag(short flag){
		field_1_option_flag = flag;
	}


	/** sets the keyboard shortcut
	 * @param shortcut keyboard shortcut
	 */
	public void setKeyboardShortcut(byte shortcut){
		field_2_keyboard_shortcut = shortcut;
	}

	/**
	 * For named ranges, and built-in names
	 * @return the 1-based sheet number.
	 */
	public int getSheetNumber()
	{
		return field_6_sheetNumber;
	}

	/**
	 * @return function group
	 * @see FnGroupCountRecord
	 */
	public byte getFnGroup() {
		int masked = field_1_option_flag & 0x0fc0;
		return (byte) (masked >> 4);
	}


	public void setSheetNumber(int value)
	{
		field_6_sheetNumber = value;
	}


	/** sets the name of the named range
	 * @param name named range name
	 */
	public void setNameText(String name){
		field_12_name_text = name;
		field_11_nameIsMultibyte = StringUtil.hasMultibyte(name);
	}

	/** sets the custom menu text
	 * @param text custom menu text
	 */
	public void setCustomMenuText(String text){
		field_14_custom_menu_text = text;
	}

	/** sets the description text
	 * @param text the description text
	 */
	public void setDescriptionText(String text){
		field_15_description_text = text;
	}

	/** sets the help topic text
	 * @param text help topix text
	 */
	public void setHelpTopicText(String text){
		field_16_help_topic_text = text;
	}

	/** sets the status bar text
	 * @param text status bar text
	 */
	public void setStatusBarText(String text){
		field_17_status_bar_text = text;
	}

	/** gets the option flag
	 * @return option flag
	 */
	public short getOptionFlag(){
		return field_1_option_flag;
	}

	/** returns the keyboard shortcut
	 * @return keyboard shortcut
	 */
	public byte getKeyboardShortcut(){
		return field_2_keyboard_shortcut ;
	}

	/**
	 * gets the name length, in characters
	 * @return name length
	 */
	private int getNameTextLength(){
		if (isBuiltInName()) {
			return 1;
		}
		return field_12_name_text.length();
	}


	/**
	 * @return true if name is hidden
	 */
	public boolean isHiddenName() {
		return (field_1_option_flag & Option.OPT_HIDDEN_NAME) != 0;
	}
	public void setHidden(boolean b) {
		if (b) {
			field_1_option_flag |= Option.OPT_HIDDEN_NAME;
		} else {
			field_1_option_flag &= (~Option.OPT_HIDDEN_NAME);
		}
	}
	/**
	 * @return <code>true</code> if name is a function
	 */
	public boolean isFunctionName() {
		return (field_1_option_flag & Option.OPT_FUNCTION_NAME) != 0;
	}

	/**
	 * Indicates that the defined name refers to a user-defined function.
	 * This attribute is used when there is an add-in or other code project associated with the file.
	 *
	 * @param function <code>true</code> indicates the name refers to a function.
	 */
	public void setFunction(boolean function){
		if (function) {
			field_1_option_flag |= Option.OPT_FUNCTION_NAME;
		} else {
			field_1_option_flag &= (~Option.OPT_FUNCTION_NAME);
		}
	}

	/**
	 * @return <code>true</code> if name has a formula (named range or defined value)
	 */
	public boolean hasFormula() {
		return Option.isFormula(field_1_option_flag) && field_13_name_definition.getEncodedTokenSize() > 0;
	}

	/**
	 * @return true if name is a command
	 */
	public boolean isCommandName() {
		return (field_1_option_flag & Option.OPT_COMMAND_NAME) != 0;
	}
	/**
	 * @return true if function macro or command macro
	 */
	public boolean isMacro() {
		return (field_1_option_flag & Option.OPT_MACRO) != 0;
	}
	/**
	 * @return true if array formula or user defined
	 */
	public boolean isComplexFunction() {
		return (field_1_option_flag & Option.OPT_COMPLEX) != 0;
	}

	/**
	 * Convenience Function to determine if the name is a built-in name
	 * 
	 * @return true, if the name is a built-in name
	 */
	public boolean isBuiltInName()
	{
		return ((field_1_option_flag & Option.OPT_BUILTIN) != 0);
	}


	/** gets the name
	 * @return name
	 */
	public String getNameText(){

		return isBuiltInName() ? translateBuiltInName(getBuiltInName()) : field_12_name_text;
	}

	/** Gets the Built In Name
	 * @return the built in Name
	 */
	public byte getBuiltInName()
	{
		return field_12_built_in_code;
	}


	/** gets the definition, reference (Formula)
	 * @return the name formula. never <code>null</code>
	 */
	public Ptg[] getNameDefinition() {
		return field_13_name_definition.getTokens();
	}

	public void setNameDefinition(Ptg[] ptgs) {
		field_13_name_definition = Formula.create(ptgs);
	}

	/** get the custom menu text
	 * @return custom menu text
	 */
	public String getCustomMenuText(){
		return field_14_custom_menu_text;
	}

	/** gets the description text
	 * @return description text
	 */
	public String getDescriptionText(){
		return field_15_description_text;
	}

	/** get the help topic text
	 * @return gelp topic text
	 */
	public String getHelpTopicText(){
		return field_16_help_topic_text;
	}

	/** gets the status bar text
	 * @return status bar text
	 */
	public String getStatusBarText(){
		return field_17_status_bar_text;
	}

    /**
     * NameRecord can span into
     *
     * @param out a data output stream
     */
	@Override
    public void serialize(ContinuableRecordOutput out) {

		int field_7_length_custom_menu = field_14_custom_menu_text.length();
		int field_8_length_description_text = field_15_description_text.length();
		int field_9_length_help_topic_text = field_16_help_topic_text.length();
		int field_10_length_status_bar_text = field_17_status_bar_text.length();

		// size defined below
		out.writeShort(getOptionFlag());
		out.writeByte(getKeyboardShortcut());
		out.writeByte(getNameTextLength());
		// Note - formula size is not immediately before encoded formula, and does not include any array constant data
		out.writeShort(field_13_name_definition.getEncodedTokenSize());
		out.writeShort(field_5_externSheetIndex_plus1);
		out.writeShort(field_6_sheetNumber);
		out.writeByte(field_7_length_custom_menu);
		out.writeByte(field_8_length_description_text);
		out.writeByte(field_9_length_help_topic_text);
		out.writeByte(field_10_length_status_bar_text);
		out.writeByte(field_11_nameIsMultibyte ? 1 : 0);

		if (isBuiltInName()) {
			//can send the builtin name directly in
			out.writeByte(field_12_built_in_code);
		} else {
			String nameText = field_12_name_text;
			if (field_11_nameIsMultibyte) {
				StringUtil.putUnicodeLE(nameText, out);
			} else {
				StringUtil.putCompressedUnicode(nameText, out);
			}
		}
		field_13_name_definition.serializeTokens(out);
		field_13_name_definition.serializeArrayConstantData(out);

		StringUtil.putCompressedUnicode( getCustomMenuText(), out);
		StringUtil.putCompressedUnicode( getDescriptionText(), out);
		StringUtil.putCompressedUnicode( getHelpTopicText(), out);
		StringUtil.putCompressedUnicode( getStatusBarText(), out);
	}
	private int getNameRawSize() {
		if (isBuiltInName()) {
			return 1;
		}
		int nChars = field_12_name_text.length();
		if(field_11_nameIsMultibyte) {
			return 2 * nChars;
		}
		return nChars;
	}

	protected int getDataSize() {
		return 13 // 3 shorts + 7 bytes
			+ getNameRawSize()
			+ field_14_custom_menu_text.length()
			+ field_15_description_text.length()
			+ field_16_help_topic_text.length()
			+ field_17_status_bar_text.length()
			+ field_13_name_definition.getEncodedSize();
	}

	/** gets the extern sheet number
	 * @return extern sheet index
	 */
	public int getExternSheetNumber(){
	    Ptg[] tokens = field_13_name_definition.getTokens();
		if (tokens.length == 0) {
			return 0;
		}

		Ptg ptg = tokens[0];
		if (ptg.getClass() == Area3DPtg.class){
			return ((Area3DPtg) ptg).getExternSheetIndex();

		}
		if (ptg.getClass() == Ref3DPtg.class){
			return ((Ref3DPtg) ptg).getExternSheetIndex();
		}
		return 0;
	}

	/**
	 * called by the constructor, should set class level fields.  Should throw
	 * runtime exception for bad/icomplete data.
	 *
	 * @param ris the RecordInputstream to read the record from
	 */
	public NameRecord(RecordInputStream ris) {
        // YK: Formula data can span into continue records, for example,
        // when containing a large array of strings. See Bugzilla 50244

        // read all remaining bytes and wrap into a LittleEndianInput
        byte[] remainder = ris.readAllContinuedRemainder();
        LittleEndianInput in = new LittleEndianByteArrayInputStream(remainder);

		field_1_option_flag                 = in.readShort();
		field_2_keyboard_shortcut           = in.readByte();
		int field_3_length_name_text        = in.readUByte();
		int field_4_length_name_definition  = in.readShort();
		field_5_externSheetIndex_plus1      = in.readShort();
		field_6_sheetNumber                 = in.readUShort();
		int f7_customMenuLen      = in.readUByte();
		int f8_descriptionTextLen = in.readUByte();
		int f9_helpTopicTextLen  = in.readUByte();
		int f10_statusBarTextLen = in.readUByte();

		//store the name in byte form if it's a built-in name
		field_11_nameIsMultibyte = (in.readByte() != 0);
		if (isBuiltInName()) {
			field_12_built_in_code = in.readByte();
		} else {
			if (field_11_nameIsMultibyte) {
				field_12_name_text = StringUtil.readUnicodeLE(in, field_3_length_name_text);
			} else {
				field_12_name_text = StringUtil.readCompressedUnicode(in, field_3_length_name_text);
			}
		}

		int nBytesAvailable = in.available() - (f7_customMenuLen
				+ f8_descriptionTextLen + f9_helpTopicTextLen + f10_statusBarTextLen);
		field_13_name_definition = Formula.read(field_4_length_name_definition, in, nBytesAvailable);

		//Who says that this can only ever be compressed unicode???
		field_14_custom_menu_text = StringUtil.readCompressedUnicode(in, f7_customMenuLen);
		field_15_description_text = StringUtil.readCompressedUnicode(in, f8_descriptionTextLen);
		field_16_help_topic_text  = StringUtil.readCompressedUnicode(in, f9_helpTopicTextLen);
		field_17_status_bar_text  = StringUtil.readCompressedUnicode(in, f10_statusBarTextLen);
	}

	/**
	 * return the non static version of the id for this record.
	 */
	@Override
    public short getSid() {
		return sid;
	}
	/*
	  20 00
	  00
	  01
	  1A 00 // sz = 0x1A = 26
	  00 00
	  01 00
	  00
	  00
	  00
	  00
	  00 // unicode flag
	  07 // name

	  29 17 00 3B 00 00 00 00 FF FF 00 00 02 00 3B 00 //{ 26
	  00 07 00 07 00 00 00 FF 00 10                   //  }



	  20 00
	  00
	  01
	  0B 00 // sz = 0xB = 11
	  00 00
	  01 00
	  00
	  00
	  00
	  00
	  00 // unicode flag
	  07 // name

	  3B 00 00 07 00 07 00 00 00 FF 00   // { 11 }
  */
	/*
	  18, 00,
	  1B, 00,

	  20, 00,
	  00,
	  01,
	  0B, 00,
	  00,
	  00,
	  00,
	  00,
	  00,
	  07,
	  3B 00 00 07 00 07 00 00 00 FF 00 ]
	 */

	@Override
    public String toString() {
		StringBuilder sb = new StringBuilder();

		sb.append("[NAME]\n");
		sb.append("    .option flags           = ").append(HexDump.shortToHex(field_1_option_flag)).append("\n");
		sb.append("    .keyboard shortcut      = ").append(HexDump.byteToHex(field_2_keyboard_shortcut)).append("\n");
		sb.append("    .length of the name     = ").append(getNameTextLength()).append("\n");
		sb.append("    .extSheetIx(1-based, 0=Global)= ").append( field_5_externSheetIndex_plus1 ).append("\n");
		sb.append("    .sheetTabIx             = ").append(field_6_sheetNumber ).append("\n");
		sb.append("    .Menu text length       = ").append(field_14_custom_menu_text.length()).append("\n");
		sb.append("    .Description text length= ").append(field_15_description_text.length()).append("\n");
		sb.append("    .Help topic text length = ").append(field_16_help_topic_text.length()).append("\n");
		sb.append("    .Status bar text length = ").append(field_17_status_bar_text.length()).append("\n");
		sb.append("    .NameIsMultibyte        = ").append(field_11_nameIsMultibyte).append("\n");
		sb.append("    .Name (Unicode text)    = ").append( getNameText() ).append("\n");
		Ptg[] ptgs = field_13_name_definition.getTokens();
		sb.append("    .Formula (nTokens=").append(ptgs.length).append("):") .append("\n");
		for (Ptg ptg : ptgs) {
			sb.append("       ").append(ptg).append(ptg.getRVAType()).append("\n");
		}

		sb.append("    .Menu text       = ").append(field_14_custom_menu_text).append("\n");
		sb.append("    .Description text= ").append(field_15_description_text).append("\n");
		sb.append("    .Help topic text = ").append(field_16_help_topic_text).append("\n");
		sb.append("    .Status bar text = ").append(field_17_status_bar_text).append("\n");
		sb.append("[/NAME]\n");

		return sb.toString();
	}

	/**Creates a human readable name for built in types
	 * @return Unknown if the built-in name cannot be translated
	 */
	private static String translateBuiltInName(byte name)
	{
		switch (name)
		{
			case NameRecord.BUILTIN_AUTO_ACTIVATE :     return "Auto_Activate";
			case NameRecord.BUILTIN_AUTO_CLOSE :        return "Auto_Close";
			case NameRecord.BUILTIN_AUTO_DEACTIVATE :   return "Auto_Deactivate";
			case NameRecord.BUILTIN_AUTO_OPEN :         return "Auto_Open";
			case NameRecord.BUILTIN_CONSOLIDATE_AREA :  return "Consolidate_Area";
			case NameRecord.BUILTIN_CRITERIA :          return "Criteria";
			case NameRecord.BUILTIN_DATABASE :          return "Database";
			case NameRecord.BUILTIN_DATA_FORM :         return "Data_Form";
			case NameRecord.BUILTIN_PRINT_AREA :        return "Print_Area";
			case NameRecord.BUILTIN_PRINT_TITLE :       return "Print_Titles";
			case NameRecord.BUILTIN_RECORDER :          return "Recorder";
			case NameRecord.BUILTIN_SHEET_TITLE :       return "Sheet_Title";
			case NameRecord.BUILTIN_FILTER_DB  :        return "_FilterDatabase";

		}

		return "Unknown";
	}
}
