/* ====================================================================
   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.
    protected int length;

    //Special info mask of this run;
    protected 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.
     */
    protected 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].
     */
    protected 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.
     */
    protected 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.
     */
    protected short bidi = -1;
    
    protected int pp10extMask = -1;
    protected 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);
    }
}
