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

import org.apache.poi.hwpf.model.ListTables;

import org.apache.poi.util.Internal;

import org.apache.poi.hwpf.model.LFO;
import org.apache.poi.hwpf.model.LFOData;
import org.apache.poi.hwpf.model.ListData;
import org.apache.poi.hwpf.model.ListFormatOverrideLevel;
import org.apache.poi.hwpf.model.ListLevel;
import org.apache.poi.hwpf.model.StyleSheet;
import org.apache.poi.hwpf.sprm.CharacterSprmCompressor;
import org.apache.poi.hwpf.sprm.ParagraphSprmCompressor;

/**
 * This class is used to create a list in a Word document. It is used in
 * conjunction with
 * {@link org.apache.poi.hwpf.HWPFDocument#registerList(HWPFList) registerList}
 * in {@link org.apache.poi.hwpf.HWPFDocument HWPFDocument}.
 * 
 * In Word, lists are not ranged entities, meaning you can't actually add one to
 * the document. Lists only act as properties for list entries. Once you
 * register a list, you can add list entries to a document that are a part of
 * the list.
 * 
 * The only benefit of this that I see, is that you can add a list entry
 * anywhere in the document and continue numbering from the previous list.
 * 
 * @author Ryan Ackley
 */
public final class HWPFList
{
    //private static POILogger log = POILogFactory.getLogger( HWPFList.class );

    private boolean _ignoreLogicalLeftIdentation = false;
    private LFO _lfo;
    private LFOData _lfoData;
    private ListData _listData;
    private ListTables _listTables;
    private boolean _registered;
    private StyleSheet _styleSheet;

    /**
     * 
     * @param numbered
     *            true if the list should be numbered; false if it should be
     *            bulleted.
     * @param styleSheet
     *            The document's stylesheet.
     */
    public HWPFList( boolean numbered, StyleSheet styleSheet )
    {
        _listData = new ListData(
                (int) ( Math.random() * System.currentTimeMillis() ), numbered );
        _lfo = new LFO();
        _lfo.setLsid( _listData.getLsid() );
        _lfoData = new LFOData();
        _styleSheet = styleSheet;
    }

    public HWPFList( StyleSheet styleSheet, ListTables listTables, int ilfo )
    {
        _listTables = listTables;
        _styleSheet = styleSheet;
        _registered = true;

        /* See documentation for sprmPIlfo (0x460B) */
        if ( ilfo == 0 || ilfo == 0xF801 )
        {
            throw new IllegalArgumentException( "Paragraph not in list" );
        }
        else if ( 0x0001 <= ilfo && ilfo <= 0x07FE )
        {
            _lfo = listTables.getLfo( ilfo );
            _lfoData = listTables.getLfoData( ilfo );
        }
        else if ( 0xF802 <= ilfo && ilfo <= 0xFFFF )
        {
            int nilfo = ilfo ^ 0xFFFF;
            _lfo = listTables.getLfo( nilfo );
            _lfoData = listTables.getLfoData( nilfo );
            _ignoreLogicalLeftIdentation = true;
        }
        else
        {
            throw new IllegalArgumentException( "Incorrect ilfo: " + ilfo );
        }

        _listData = listTables.getListData( _lfo.getLsid() );
    }

    @Internal
    public LFO getLFO()
    {
        return _lfo;
    }

    @Internal
    public LFOData getLFOData()
    {
        return _lfoData;
    }

    @Internal
    public ListData getListData()
    {
        return _listData;
    }

    public int getLsid()
    {
        return _lfo.getLsid();
    }

    @Internal
    ListLevel getLVL( char level )
    {
        if ( level >= _listData.numLevels() )
        {
            throw new IllegalArgumentException( "Required level "
                    + ( (int) level )
                    + " is more than number of level for list ("
                    + _listData.numLevels() + ")" );
        }
        ListLevel lvl = _listData.getLevels()[level];
        return lvl;
    }

    /**
     * An MSONFC, as specified in [MS-OSHARED] section 2.2.1.3, that specifies
     * the format of the level numbers that replace the placeholders for this
     * level in the xst fields of the LVLs in this list. This value MUST not be
     * equal to 0x08, 0x09, 0x0F, or 0x13. If this is equal to 0xFF or 0x17,
     * this level does not have a number sequence and therefore has no number
     * formatting. If this is equal to 0x17, the level uses bullets.
     */
    public int getNumberFormat( char level )
    {
        return getLVL( level ).getNumberFormat();
    }

    public String getNumberText( char level )
    {
        return getLVL( level ).getNumberText();
    }

    public int getStartAt( char level )
    {
        if ( isStartAtOverriden( level ) )
        {
            return _lfoData.getRgLfoLvl()[level].getIStartAt();
        }

        return getLVL( level ).getStartAt();
    }

    /**
     * "The type of character following the number text for the paragraph: 0 == tab, 1 == space, 2 == nothing."
     */
    public byte getTypeOfCharFollowingTheNumber( char level )
    {
        return getLVL( level ).getTypeOfCharFollowingTheNumber();
    }

    public boolean isIgnoreLogicalLeftIdentation()
    {
        return _ignoreLogicalLeftIdentation;
    }

    public boolean isStartAtOverriden( char level )
    {
        ListFormatOverrideLevel lfolvl = _lfoData.getRgLfoLvl().length > level ? _lfoData
                .getRgLfoLvl()[level] : null;

        return lfolvl != null && lfolvl.getIStartAt() != 0
                && !lfolvl.isFormatting();
    }

    public void setIgnoreLogicalLeftIdentation(
            boolean ignoreLogicalLeftIdentation )
    {
        this._ignoreLogicalLeftIdentation = ignoreLogicalLeftIdentation;
    }

    /**
     * Sets the character properties of the list numbers.
     * 
     * @param level
     *            the level number that the properties should apply to.
     * @param chp
     *            The character properties.
     */
    public void setLevelNumberProperties( int level, CharacterProperties chp )
    {
        ListLevel listLevel = _listData.getLevel( level );
        int styleIndex = _listData.getLevelStyle( level );
        CharacterProperties base = _styleSheet.getCharacterStyle( styleIndex );

        byte[] grpprl = CharacterSprmCompressor.compressCharacterProperty( chp,
                base );
        listLevel.setNumberProperties( grpprl );
    }

    /**
     * Sets the paragraph properties for a particular level of the list.
     * 
     * @param level
     *            The level number.
     * @param pap
     *            The paragraph properties
     */
    public void setLevelParagraphProperties( int level, ParagraphProperties pap )
    {
        ListLevel listLevel = _listData.getLevel( level );
        int styleIndex = _listData.getLevelStyle( level );
        ParagraphProperties base = _styleSheet.getParagraphStyle( styleIndex );

        byte[] grpprl = ParagraphSprmCompressor.compressParagraphProperty( pap,
                base );
        listLevel.setLevelProperties( grpprl );
    }

    public void setLevelStyle( int level, int styleIndex )
    {
        _listData.setLevelStyle( level, styleIndex );
    }
}
