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

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.HWPFDocumentCore;
import org.apache.poi.hwpf.HWPFOldDocument;
import org.apache.poi.hwpf.OldWordFileFormatException;
import org.apache.poi.hwpf.usermodel.BorderCode;
import org.apache.poi.hwpf.usermodel.HWPFList;
import org.apache.poi.hwpf.usermodel.Table;
import org.apache.poi.hwpf.usermodel.TableCell;
import org.apache.poi.hwpf.usermodel.TableRow;
import org.apache.poi.poifs.filesystem.DirectoryNode;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.Beta;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

@Beta
public class AbstractWordUtils
{
    static final String EMPTY = "";

    private static final POILogger logger = POILogFactory
            .getLogger( AbstractWordUtils.class );

    public static final float TWIPS_PER_INCH = 1440.0f;
    public static final int TWIPS_PER_PT = 20;

    /**
     * Creates array of all possible cell edges. In HTML (and FO) cells from
     * different rows and same column should have same width, otherwise spanning
     * shall be used.
     * 
     * @param table
     *            table to build cell edges array from
     * @return array of cell edges (including leftest one) in twips
     */
    static int[] buildTableCellEdgesArray( Table table )
    {
        Set<Integer> edges = new TreeSet<Integer>();

        for ( int r = 0; r < table.numRows(); r++ )
        {
            TableRow tableRow = table.getRow( r );
            for ( int c = 0; c < tableRow.numCells(); c++ )
            {
                TableCell tableCell = tableRow.getCell( c );

                edges.add( Integer.valueOf( tableCell.getLeftEdge() ) );
                edges.add( Integer.valueOf( tableCell.getLeftEdge()
                        + tableCell.getWidth() ) );
            }
        }

        Integer[] sorted = edges.toArray( new Integer[edges.size()] );
        int[] result = new int[sorted.length];
        for ( int i = 0; i < sorted.length; i++ )
        {
            result[i] = sorted[i].intValue();
        }

        return result;
    }

    static boolean canBeMerged( Node node1, Node node2, String requiredTagName )
    {
        if ( node1.getNodeType() != Node.ELEMENT_NODE
                || node2.getNodeType() != Node.ELEMENT_NODE )
            return false;

        Element element1 = (Element) node1;
        Element element2 = (Element) node2;

        if ( !equals( requiredTagName, element1.getTagName() )
                || !equals( requiredTagName, element2.getTagName() ) )
            return false;

        NamedNodeMap attributes1 = element1.getAttributes();
        NamedNodeMap attributes2 = element2.getAttributes();

        if ( attributes1.getLength() != attributes2.getLength() )
            return false;

        for ( int i = 0; i < attributes1.getLength(); i++ )
        {
            final Attr attr1 = (Attr) attributes1.item( i );
            final Attr attr2;
            if ( isNotEmpty( attr1.getNamespaceURI() ) )
                attr2 = (Attr) attributes2.getNamedItemNS(
                        attr1.getNamespaceURI(), attr1.getLocalName() );
            else
                attr2 = (Attr) attributes2.getNamedItem( attr1.getName() );

            if ( attr2 == null
                    || !equals( attr1.getTextContent(), attr2.getTextContent() ) )
                return false;
        }

        return true;
    }

    static void compactChildNodesR( Element parentElement, String childTagName )
    {
        NodeList childNodes = parentElement.getChildNodes();
        for ( int i = 0; i < childNodes.getLength() - 1; i++ )
        {
            Node child1 = childNodes.item( i );
            Node child2 = childNodes.item( i + 1 );
            if ( !WordToFoUtils.canBeMerged( child1, child2, childTagName ) )
                continue;

            // merge
            while ( child2.getChildNodes().getLength() > 0 )
                child1.appendChild( child2.getFirstChild() );
            child2.getParentNode().removeChild( child2 );
            i--;
        }

        childNodes = parentElement.getChildNodes();
        for ( int i = 0; i < childNodes.getLength() - 1; i++ )
        {
            Node child = childNodes.item( i );
            if ( child instanceof Element )
            {
                compactChildNodesR( (Element) child, childTagName );
            }
        }
    }

    static boolean equals( String str1, String str2 )
    {
        return str1 == null ? str2 == null : str1.equals( str2 );
    }

    public static String getBorderType( BorderCode borderCode )
    {
        if ( borderCode == null )
            throw new IllegalArgumentException( "borderCode is null" );

        switch ( borderCode.getBorderType() )
        {
        case 1:
        case 2:
            return "solid";
        case 3:
            return "double";
        case 5:
            return "solid";
        case 6:
            return "dotted";
        case 7:
        case 8:
            return "dashed";
        case 9:
            return "dotted";
        case 10:
        case 11:
        case 12:
        case 13:
        case 14:
        case 15:
        case 16:
        case 17:
        case 18:
        case 19:
            return "double";
        case 20:
            return "solid";
        case 21:
            return "double";
        case 22:
            return "dashed";
        case 23:
            return "dashed";
        case 24:
            return "ridge";
        case 25:
            return "grooved";
        default:
            return "solid";
        }
    }

    public static String getBorderWidth( BorderCode borderCode )
    {
        int lineWidth = borderCode.getLineWidth();
        int pt = lineWidth / 8;
        int pte = lineWidth - pt * 8;

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append( pt );
        stringBuilder.append( "." );
        stringBuilder.append( 1000 / 8 * pte );
        stringBuilder.append( "pt" );
        return stringBuilder.toString();
    }

    public static class NumberingState
    {

        private final Map<String, Integer> levels = new HashMap<String, Integer>();

    }

    public static String getBulletText( NumberingState numberingState,
            HWPFList list, char level )
    {
        StringBuffer bulletBuffer = new StringBuffer();
        char[] xst = list.getNumberText( level ).toCharArray();
        for ( char element : xst )
        {
            if ( element < 9 )
            {
                int lsid = list.getLsid();
                final String key = lsid + "#" + ( (int) element );
                int num;

                if ( !list.isStartAtOverriden( element )
                        && numberingState.levels.containsKey( key ) )
                {
                    num = numberingState.levels.get( key ).intValue();
                    if ( level == element )
                    {
                        num++;
                        numberingState.levels.put( key, Integer.valueOf( num ) );
                    }
                }
                else
                {
                    num = list.getStartAt( element );
                    numberingState.levels.put( key, Integer.valueOf( num ) );
                }

                if ( level == element )
                {
                    // cleaning states of nested levels to reset numbering
                    for ( int i = element + 1; i < 9; i++ )
                    {
                        final String childKey = lsid + "#" + i;
                        numberingState.levels.remove( childKey );
                    }
                }
                
                bulletBuffer.append( NumberFormatter.getNumber( num,
                        list.getNumberFormat( level ) ) );
            }
            else
            {
                bulletBuffer.append( element );
            }
        }

        byte follow = list.getTypeOfCharFollowingTheNumber( level );
        switch ( follow )
        {
        case 0:
            bulletBuffer.append( "\t" );
            break;
        case 1:
            bulletBuffer.append( " " );
            break;
        default:
            break;
        }

        return bulletBuffer.toString();
    }

    public static String getColor( int ico )
    {
        switch ( ico )
        {
        case 1:
            return "black";
        case 2:
            return "blue";
        case 3:
            return "cyan";
        case 4:
            return "green";
        case 5:
            return "magenta";
        case 6:
            return "red";
        case 7:
            return "yellow";
        case 8:
            return "white";
        case 9:
            return "darkblue";
        case 10:
            return "darkcyan";
        case 11:
            return "darkgreen";
        case 12:
            return "darkmagenta";
        case 13:
            return "darkred";
        case 14:
            return "darkyellow";
        case 15:
            return "darkgray";
        case 16:
            return "lightgray";
        default:
            return "black";
        }
    }

    public static String getOpacity( int argbValue )
    {
        int opacity = (int) ( ( argbValue & 0xFF000000l ) >>> 24 );
        if ( opacity == 0 || opacity == 0xFF )
            return ".0";

        return "" + ( opacity / (float) 0xFF );
    }

    public static String getColor24( int argbValue )
    {
        if ( argbValue == -1 )
            throw new IllegalArgumentException( "This colorref is empty" );

        int bgrValue = argbValue & 0x00FFFFFF;
        int rgbValue = ( bgrValue & 0x0000FF ) << 16 | ( bgrValue & 0x00FF00 )
                | ( bgrValue & 0xFF0000 ) >> 16;

        // http://www.w3.org/TR/REC-html40/types.html#h-6.5
        switch ( rgbValue )
        {
        case 0xFFFFFF:
            return "white";
        case 0xC0C0C0:
            return "silver";
        case 0x808080:
            return "gray";
        case 0x000000:
            return "black";
        case 0xFF0000:
            return "red";
        case 0x800000:
            return "maroon";
        case 0xFFFF00:
            return "yellow";
        case 0x808000:
            return "olive";
        case 0x00FF00:
            return "lime";
        case 0x008000:
            return "green";
        case 0x00FFFF:
            return "aqua";
        case 0x008080:
            return "teal";
        case 0x0000FF:
            return "blue";
        case 0x000080:
            return "navy";
        case 0xFF00FF:
            return "fuchsia";
        case 0x800080:
            return "purple";
        }

        StringBuilder result = new StringBuilder( "#" );
        String hex = Integer.toHexString( rgbValue );
        for ( int i = hex.length(); i < 6; i++ )
        {
            result.append( '0' );
        }
        result.append( hex );
        return result.toString();
    }

    public static String getJustification( int js )
    {
        switch ( js )
        {
        case 0:
            return "start";
        case 1:
            return "center";
        case 2:
            return "end";
        case 3:
        case 4:
            return "justify";
        case 5:
            return "center";
        case 6:
            return "left";
        case 7:
            return "start";
        case 8:
            return "end";
        case 9:
            return "justify";
        }
        return "";
    }

    public static String getLanguage( int languageCode )
    {
        switch ( languageCode )
        {
        case 1024:
            return EMPTY;
        case 1033:
            return "en-us";
        case 1049:
            return "ru-ru";
        case 2057:
            return "en-uk";
        default:
            logger.log( POILogger.WARN, "Uknown or unmapped language code: ",
                    Integer.valueOf( languageCode ) );
            return EMPTY;
        }
    }

    public static String getListItemNumberLabel( int number, int format )
    {

        if ( format != 0 )
        	logger.log( POILogger.INFO, "NYI: toListItemNumberLabel(): " + format );

        return String.valueOf( number );
    }

    static boolean isEmpty( String str )
    {
        return str == null || str.length() == 0;
    }

    static boolean isNotEmpty( String str )
    {
        return !isEmpty( str );
    }

    public static HWPFDocumentCore loadDoc( final DirectoryNode root )
            throws IOException
    {
        try
        {
            return new HWPFDocument( root );
        }
        catch ( OldWordFileFormatException exc )
        {
            return new HWPFOldDocument( root );
        }
    }

    public static HWPFDocumentCore loadDoc( File docFile ) throws IOException
    {
        final FileInputStream istream = new FileInputStream( docFile );
        try {
            return loadDoc( istream );
        } finally {
            istream.close();
        }
    }

    public static HWPFDocumentCore loadDoc( InputStream inputStream )
            throws IOException
    {
        return loadDoc( HWPFDocumentCore.verifyAndBuildPOIFS( inputStream ) );
    }

    public static HWPFDocumentCore loadDoc(
            final POIFSFileSystem poifsFileSystem ) throws IOException
    {
        return loadDoc( poifsFileSystem.getRoot() );
    }

    static String substringBeforeLast( String str, String separator )
    {
        if ( isEmpty( str ) || isEmpty( separator ) )
        {
            return str;
        }
        int pos = str.lastIndexOf( separator );
        if ( pos == -1 )
        {
            return str;
        }
        return str.substring( 0, pos );
    }

}
