/* ====================================================================
   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.hslf.record;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.poi.util.*;

public class TextSpecInfoRun {
    /**
     * A enum that specifies the spelling status of a run of text.
     */
    public enum SpellInfoEnum {
        /** the text is spelled incorrectly. */
        error(new BitField(1)),
        /** the text needs rechecking. */
        clean(new BitField(2)),
        /** the text has a grammar error. */
        grammar(new BitField(4)),
        /** the text is spelled correct */
        correct(new BitField(0));
        
        final BitField bitField;
        
        SpellInfoEnum(BitField bitField) {
            this.bitField = bitField;
        }
    }
    
    /** A bit that specifies whether the spellInfo field exists. */
    private static final BitField spellFld    = new BitField(0X00000001);
    /** A bit that specifies whether the lid field exists. */
    private static final BitField langFld     = new BitField(0X00000002);
    /** A bit that specifies whether the altLid field exists. */
    private static final BitField altLangFld  = new BitField(0X00000004);
    // unused1, unused2 - Undefined and MUST be ignored.
    /** A bit that specifies whether the pp10runid, reserved3, and grammarError fields exist. */
    private static final BitField pp10extFld  = new BitField(0X00000020);
    /** A bit that specifies whether the bidi field exists. */
    private static final BitField bidiFld     = new BitField(0X00000040);
    // unused3 - Undefined and MUST be ignored.
    // reserved1 - MUST be zero and MUST be ignored.
    /** A bit that specifies whether the smartTags field exists. */
    private static final BitField smartTagFld = new BitField(0X00000200);
    // reserved2 - MUST be zero and MUST be ignored. 

    /**
     * An optional unsigned integer that specifies an identifier for a character
     * run that contains StyleTextProp11 data. It MUST exist if and only if pp10ext is TRUE.
     **/
    private static final BitField pp10runidFld = new BitField(0X0000000F);
    // reserved3 - An optional unsigned integer that MUST be zero, and MUST be ignored. It
    // MUST exist if and only if fPp10ext is TRUE.
    /**
     * An optional bit that specifies a grammar error. It MUST exist if and
     * only if fPp10ext is TRUE.
     **/
    private static final BitField grammarErrorFld = new BitField(0X80000000);
    
    //Length of special info run.
    private int length;

    //Special info mask of this run;
    private int mask;

    // info fields as indicated by the mask.
    // -1 means the bit is not set

    /**
     * An optional SpellingFlags structure that specifies the spelling status of this
     * text. It MUST exist if and only if spell is TRUE.
     * The spellInfo.grammar sub-field MUST be zero.
     * <br>
     * error (1 bit): A bit that specifies whether the text is spelled incorrectly.<br>
     * clean (1 bit): A bit that specifies whether the text needs rechecking.<br>
     * grammar (1 bit): A bit that specifies whether the text has a grammar error.<br>
     * reserved (13 bits): MUST be zero and MUST be ignored.
     */
    private short spellInfo = -1;
    
    /**
     * An optional TxLCID that specifies the language identifier of this text.
     * It MUST exist if and only if lang is TRUE.
     * <br>
     * 0x0000 = No language.<br>
     * 0x0013 = Any Dutch language is preferred over non-Dutch languages when proofing the text.<br>
     * 0x0400 = No proofing is performed on the text.<br>
     * &gt; 0x0400 = A valid LCID as specified by [MS-LCID].
     */
    private short langId = -1;
    
    /**
     * An optional TxLCID that specifies the alternate language identifier of this text.
     * It MUST exist if and only if altLang is TRUE.
     */
    private short altLangId = -1;
    
    /**
     * An optional signed integer that specifies whether the text contains bidirectional
     * characters. It MUST exist if and only if fBidi is TRUE.
     * 0x0000 = Contains no bidirectional characters,
     * 0x0001 = Contains bidirectional characters.
     */
    private short bidi = -1;
    
    private int pp10extMask = -1;
    private byte[] smartTagsBytes = null;

    /**
     * Inits a TextSpecInfoRun with default values
     *
     * @param len the length of the one and only run
     */
    public TextSpecInfoRun(int len) {
        setLength(len);
        setLangId((short)0);
    }
    
    public TextSpecInfoRun(LittleEndianByteArrayInputStream source) {
        length = source.readInt();
        mask = source.readInt();
        if (spellFld.isSet(mask)) {
            spellInfo = source.readShort();
        }
        if (langFld.isSet(mask)) {
            langId = source.readShort();
        }
        if (altLangFld.isSet(mask)) {
            altLangId = source.readShort();
        }
        if (bidiFld.isSet(mask)) {
            bidi = source.readShort();
        }
        if (pp10extFld.isSet(mask)) {
            pp10extMask = source.readInt();
        }
        if (smartTagFld.isSet(mask)) {
            // An unsigned integer specifies the count of items in rgSmartTagIndex.
            int count = source.readInt();
            smartTagsBytes = new byte[4+count*4];
            LittleEndian.putInt(smartTagsBytes, 0, count);
            // An array of SmartTagIndex that specifies the indices.
            // The count of items in the array is specified by count.
            source.readFully(smartTagsBytes, 4, count*4);
        }
    }

    /**
     * Write the contents of the record back, so it can be written
     * to disk
     *
     * @param out the output stream to write to.
     * @throws java.io.IOException if an error occurs.
     */
    public void writeOut(OutputStream out) throws IOException {
        final byte buf[] = new byte[4];
        LittleEndian.putInt(buf, 0, length);
        out.write(buf);
        LittleEndian.putInt(buf, 0, mask);
        out.write(buf);
        Object flds[] = {
            spellFld, spellInfo, "spell info",
            langFld, langId, "lang id",
            altLangFld, altLangId, "alt lang id",
            bidiFld, bidi, "bidi",
            pp10extFld, pp10extMask, "pp10 extension field",
            smartTagFld, smartTagsBytes, "smart tags"
        };
        
        for (int i=0; i<flds.length; i+=3) {
            BitField fld = (BitField)flds[i+0];
            Object valO = flds[i+1];
            if (!fld.isSet(mask)) continue;
            boolean valid;
            if (valO instanceof byte[]) {
                byte bufB[] = (byte[])valO;
                valid = bufB.length > 0;
                out.write(bufB);
            } else if (valO instanceof Integer) {
                int valI = ((Integer)valO);
                valid = (valI != -1);
                LittleEndian.putInt(buf, 0, valI);
                out.write(buf);
            } else if (valO instanceof Short) {
                short valS = ((Short)valO);
                valid = (valS != -1);
                LittleEndian.putShort(buf, 0, valS);
                out.write(buf, 0, 2);
            } else {
                valid = false;
            }
            if (!valid) {
                throw new IOException(flds[i+2]+" is activated, but its value is invalid");
            }
        }
    }        
    
    /**
     * @return Spelling status of this text. null if not defined.
     */
    public SpellInfoEnum getSpellInfo(){
        if (spellInfo == -1) return null;
        for (SpellInfoEnum si : new SpellInfoEnum[]{SpellInfoEnum.clean,SpellInfoEnum.error,SpellInfoEnum.grammar}) {
            if (si.bitField.isSet(spellInfo)) return si;
        }
        return SpellInfoEnum.correct;
    }

    /**
     * @param spellInfo Spelling status of this text. null if not defined.
     */
    public void setSpellInfo(SpellInfoEnum spellInfo) {
        this.spellInfo = (spellInfo == null)
            ? -1
            : (short)spellInfo.bitField.set(0);
        mask = spellFld.setBoolean(mask, spellInfo != null);
    }
    
    /**
     * Windows LANGID for this text.
     *
     * @return Windows LANGID for this text, -1 if it's not set
     */
    public short getLangId(){
        return langId;
    }

    /**
     * @param langId Windows LANGID for this text, -1 to unset
     */
    public void setLangId(short langId) {
        this.langId = langId;
        mask = langFld.setBoolean(mask, langId != -1);
    }
    
    /**
     * Alternate Windows LANGID of this text;
     * must be a valid non-East Asian LANGID if the text has an East Asian language,
     * otherwise may be an East Asian LANGID or language neutral (zero).
     *
     * @return  Alternate Windows LANGID of this text, -1 if it's not set
     */
    public short getAltLangId(){
        return altLangId;
    }

    public void setAltLangId(short altLangId) {
        this.altLangId = altLangId;
        mask = altLangFld.setBoolean(mask, altLangId != -1);
    }

    /**
     * @return Length of special info run.
     */
    public int getLength() {
        return length;
    }

    /**
     * @param length Length of special info run.
     */
    public void setLength(int length) {
        this.length = length;
    }

    /**
     * @return the bidirectional characters flag. false = not bidi, true = is bidi, null = not set
     */
    public Boolean getBidi() {
        return (bidi == -1 ? null : bidi != 0);
    }

    /**
     * @param bidi the bidirectional characters flag. false = not bidi, true = is bidi, null = not set
     */
    public void setBidi(Boolean bidi) {
        this.bidi = (bidi == null) ? -1 : (short)(bidi ? 1 : 0);
        mask = bidiFld.setBoolean(mask, bidi != null);
    }

    /**
     * @return the unparsed smart tags
     */
    public byte[] getSmartTagsBytes() {
        return smartTagsBytes;
    }

    /**
     * @param smartTagsBytes the unparsed smart tags, null to unset
     */
    public void setSmartTagsBytes(byte[] smartTagsBytes) {
        this.smartTagsBytes = (smartTagsBytes == null) ? null : smartTagsBytes.clone();
        mask = smartTagFld.setBoolean(mask, smartTagsBytes != null);
    }
    
    /**
     * @return an identifier for a character run that contains StyleTextProp11 data.
     */
    public int getPP10RunId() {
        return (pp10extMask == -1 || !pp10extFld.isSet(mask)) ? -1 : pp10runidFld.getValue(pp10extMask);
        
    }
    
    /**
     * @param pp10RunId an identifier for a character run that contains StyleTextProp11 data, -1 to unset
     */
    public void setPP10RunId(int pp10RunId) {
        if (pp10RunId == -1) {
            pp10extMask = (getGrammarError() == null) ? -1 : pp10runidFld.clear(pp10extMask);
        } else {
            pp10extMask = pp10runidFld.setValue(pp10extMask, pp10RunId);
        }
        // if both parameters are invalid, remove the extension mask
        mask = pp10extFld.setBoolean(mask, pp10extMask != -1);
    }
    
    public Boolean getGrammarError() {
        return (pp10extMask == -1 || !pp10extFld.isSet(mask)) ? null : grammarErrorFld.isSet(pp10extMask);
    }
    
    public void getGrammarError(Boolean grammarError) {
        if (grammarError == null) {
            pp10extMask = (getPP10RunId() == -1) ? -1 : grammarErrorFld.clear(pp10extMask);
        } else {
            pp10extMask = grammarErrorFld.set(pp10extMask);
        }
        // if both parameters are invalid, remove the extension mask
        mask = pp10extFld.setBoolean(mask, pp10extMask != -1);
    }
}
