/*
 * 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.
 */

/* $Id$ */

package org.apache.fop.fonts;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.fop.text.bidi.BidiClassUtils;
import org.apache.fop.util.BidiConstants;

// CSOFF: AvoidNestedBlocksCheck
// CSOFF: NoWhitespaceAfterCheck
// CSOFF: InnerAssignmentCheck
// CSOFF: SimplifyBooleanReturnCheck
// CSOFF: LineLengthCheck

/**
 * <p>The <code>ArabicScriptProcessor</code> class implements a script processor for
 * performing glyph substitution and positioning operations on content associated with the Arabic script.</p>
 * @author Glenn Adams
 */
public class ArabicScriptProcessor extends DefaultScriptProcessor {

    /** logging instance */
    private static final Log log = LogFactory.getLog(ArabicScriptProcessor.class);                                      // CSOK: ConstantNameCheck

    /** features to use for substitutions */
    private static final String[] gsubFeatures =                                                                        // CSOK: ConstantNameCheck
    {
        "calt",                                                 // contextual alternates
        "ccmp",                                                 // glyph composition/decomposition
        "fina",                                                 // final (terminal) forms
        "init",                                                 // initial forms
        "isol",                                                 // isolated formas
        "liga",                                                 // standard ligatures
        "medi",                                                 // medial forms
        "rlig"                                                  // required ligatures
    };

    /** features to use for positioning */
    private static final String[] gposFeatures =                                                                        // CSOK: ConstantNameCheck
    {
        "curs",                                                 // cursive positioning
        "kern",                                                 // kerning
        "mark",                                                 // mark to base or ligature positioning
        "mkmk"                                                  // mark to mark positioning
    };

    private static class SubstitutionScriptContextTester implements ScriptContextTester {
        private static Map/*<String,GlyphContextTester>*/ testerMap = new HashMap/*<String,GlyphContextTester>*/();
        static {
            testerMap.put ( "fina", new GlyphContextTester() {
                    public boolean test ( String script, String language, String feature, GlyphSequence gs, int index ) {
                        return inFinalContext ( script, language, feature, gs, index );
                    }
                } );
            testerMap.put ( "init", new GlyphContextTester() {
                    public boolean test ( String script, String language, String feature, GlyphSequence gs, int index ) {
                        return inInitialContext ( script, language, feature, gs, index );
                    }
                } );
            testerMap.put ( "isol", new GlyphContextTester() {
                    public boolean test ( String script, String language, String feature, GlyphSequence gs, int index ) {
                        return inIsolateContext ( script, language, feature, gs, index );
                    }
                } );
            testerMap.put ( "liga", new GlyphContextTester() {
                    public boolean test ( String script, String language, String feature, GlyphSequence gs, int index ) {
                        return inLigatureContext ( script, language, feature, gs, index );
                    }
                } );
            testerMap.put ( "medi", new GlyphContextTester() {
                    public boolean test ( String script, String language, String feature, GlyphSequence gs, int index ) {
                        return inMedialContext ( script, language, feature, gs, index );
                    }
                } );
        }
        public GlyphContextTester getTester ( String feature ) {
            return (GlyphContextTester) testerMap.get ( feature );
        }
    }

    private static class PositioningScriptContextTester implements ScriptContextTester {
        private static Map/*<String,GlyphContextTester>*/ testerMap = new HashMap/*<String,GlyphContextTester>*/();
        public GlyphContextTester getTester ( String feature ) {
            return (GlyphContextTester) testerMap.get ( feature );
        }
    }

    private final ScriptContextTester subContextTester;
    private final ScriptContextTester posContextTester;

    ArabicScriptProcessor ( String script ) {
        super ( script );
        this.subContextTester = new SubstitutionScriptContextTester();
        this.posContextTester = new PositioningScriptContextTester();
    }

    /** {@inheritDoc} */
    public String[] getSubstitutionFeatures() {
        return gsubFeatures;
    }

    /** {@inheritDoc} */
    public ScriptContextTester getSubstitutionContextTester() {
        return subContextTester;
    }

    /** {@inheritDoc} */
    public String[] getPositioningFeatures() {
        return gposFeatures;
    }

    /** {@inheritDoc} */
    public ScriptContextTester getPositioningContextTester() {
        return posContextTester;
    }

    /** {@inheritDoc} */
    @Override
    public GlyphSequence reorderCombiningMarks ( GlyphDefinitionTable gdef, GlyphSequence gs, int[][] gpa, String script, String language ) {
        // a side effect of BIDI reordering is to order combining marks before their base, so we need to override the default here to
        // prevent double reordering
        return gs;
    }

    private static boolean inFinalContext ( String script, String language, String feature, GlyphSequence gs, int index ) {
        GlyphSequence.CharAssociation a = gs.getAssociation ( index );
        int[] ca = gs.getCharacterArray ( false );
        int   nc = gs.getCharacterCount();
        if ( nc == 0 ) {
            return false;
        } else {
            int s = a.getStart();
            int e = a.getEnd();
            if ( ! hasFinalPrecedingContext ( ca, nc, s, e ) ) {
                return false;
            } else if ( forcesFinalThisContext ( ca, nc, s, e ) ) {
                return true;
            } else if ( ! hasFinalFollowingContext ( ca, nc, s, e ) ) {
                return false;
            } else {
                return true;
            }
        }
    }

    private static boolean inInitialContext ( String script, String language, String feature, GlyphSequence gs, int index ) {
        GlyphSequence.CharAssociation a = gs.getAssociation ( index );
        int[] ca = gs.getCharacterArray ( false );
        int   nc = gs.getCharacterCount();
        if ( nc == 0 ) {
            return false;
        } else {
            int s = a.getStart();
            int e = a.getEnd();
            if ( ! hasInitialPrecedingContext ( ca, nc, s, e ) ) {
                return false;
            } else if ( ! hasInitialFollowingContext ( ca, nc, s, e ) ) {
                return false;
            } else {
                return true;
            }
        }
    }

    private static boolean inIsolateContext ( String script, String language, String feature, GlyphSequence gs, int index ) {
        GlyphSequence.CharAssociation a = gs.getAssociation ( index );
        int   nc = gs.getCharacterCount();
        if ( nc == 0 ) {
            return false;
        } else if ( ( a.getStart() == 0 ) && ( a.getEnd() == nc ) ) {
            return true;
        } else {
            return false;
        }
    }

    private static boolean inLigatureContext ( String script, String language, String feature, GlyphSequence gs, int index ) {
        GlyphSequence.CharAssociation a = gs.getAssociation ( index );
        int[] ca = gs.getCharacterArray ( false );
        int   nc = gs.getCharacterCount();
        if ( nc == 0 ) {
            return false;
        } else {
            int s = a.getStart();
            int e = a.getEnd();
            if ( ! hasLigaturePrecedingContext ( ca, nc, s, e ) ) {
                return false;
            } else if ( ! hasLigatureFollowingContext ( ca, nc, s, e ) ) {
                return false;
            } else {
                return true;
            }
        }
    }

    private static boolean inMedialContext ( String script, String language, String feature, GlyphSequence gs, int index ) {
        GlyphSequence.CharAssociation a = gs.getAssociation ( index );
        int[] ca = gs.getCharacterArray ( false );
        int   nc = gs.getCharacterCount();
        if ( nc == 0 ) {
            return false;
        } else {
            int s = a.getStart();
            int e = a.getEnd();
            if ( ! hasMedialPrecedingContext ( ca, nc, s, e ) ) {
                return false;
            } else if ( ! hasMedialThisContext ( ca, nc, s, e ) ) {
                return false;
            } else if ( ! hasMedialFollowingContext ( ca, nc, s, e ) ) {
                return false;
            } else {
                return true;
            }
        }
    }

    private static boolean hasFinalPrecedingContext ( int[] ca, int nc, int s, int e ) {
        int chp = 0;
        int clp = 0;
        for ( int i = s; i > 0; i-- ) {
            int k = i - 1;
            if ( ( k >= 0 ) && ( k < nc ) ) {
                chp = ca [ k ];
                clp = BidiClassUtils.getBidiClass ( chp );
                if ( clp != BidiConstants.NSM ) {
                    break;
                }
            }
        }
        if ( clp != BidiConstants.AL ) {
            return false;
        } else if ( hasIsolateInitial ( chp ) ) {
            return false;
        } else {
            return true;
        }
    }

    private static boolean forcesFinalThisContext ( int[] ca, int nc, int s, int e ) {
        int chl = 0;
        int cll = 0;
        for ( int i = 0, n = e - s; i < n; i++ ) {
            int k = n - i - 1;
            int j = s + k;
            if ( ( j >= 0 ) && ( j < nc ) ) {
                chl = ca [ j ];
                cll = BidiClassUtils.getBidiClass ( chl );
                if ( cll != BidiConstants.NSM ) {
                    break;
                }
            }
        }
        if ( cll != BidiConstants.AL ) {
            return false;
        }
        if ( hasIsolateInitial ( chl ) ) {
            return true;
        } else {
            return false;
        }
    }

    private static boolean hasFinalFollowingContext ( int[] ca, int nc, int s, int e ) {
        int chf = 0;
        int clf = 0;
        for ( int i = e, n = nc; i < n; i++ ) {
            chf = ca [ i ];
            clf = BidiClassUtils.getBidiClass ( chf );
            if ( clf != BidiConstants.NSM ) {
                break;
            }
        }
        if ( clf != BidiConstants.AL ) {
            return true;
        } else if ( hasIsolateFinal ( chf ) ) {
            return true;
        } else {
            return false;
        }
    }

    private static boolean hasInitialPrecedingContext ( int[] ca, int nc, int s, int e ) {
        int chp = 0;
        int clp = 0;
        for ( int i = s; i > 0; i-- ) {
            int k = i - 1;
            if ( ( k >= 0 ) && ( k < nc ) ) {
                chp = ca [ k ];
                clp = BidiClassUtils.getBidiClass ( chp );
                if ( clp != BidiConstants.NSM ) {
                    break;
                }
            }
        }
        if ( clp != BidiConstants.AL ) {
            return true;
        } else if ( hasIsolateInitial ( chp ) ) {
            return true;
        } else {
            return false;
        }
    }

    private static boolean hasInitialFollowingContext ( int[] ca, int nc, int s, int e ) {
        int chf = 0;
        int clf = 0;
        for ( int i = e, n = nc; i < n; i++ ) {
            chf = ca [ i ];
            clf = BidiClassUtils.getBidiClass ( chf );
            if ( clf != BidiConstants.NSM ) {
                break;
            }
        }
        if ( clf != BidiConstants.AL ) {
            return false;
        } else if ( hasIsolateFinal ( chf ) ) {
            return false;
        } else {
            return true;
        }
    }

    private static boolean hasMedialPrecedingContext ( int[] ca, int nc, int s, int e ) {
        int chp = 0;
        int clp = 0;
        for ( int i = s; i > 0; i-- ) {
            int k = i - 1;
            if ( ( k >= 0 ) && ( k < nc ) ) {
                chp = ca [ k ];
                clp = BidiClassUtils.getBidiClass ( chp );
                if ( clp != BidiConstants.NSM ) {
                    break;
                }
            }
        }
        if ( clp != BidiConstants.AL ) {
            return false;
        } else if ( hasIsolateInitial ( chp ) ) {
            return false;
        } else {
            return true;
        }
    }

    private static boolean hasMedialThisContext ( int[] ca, int nc, int s, int e ) {
        int chf = 0;    // first non-NSM char in [s,e)
        int clf = 0;
        for ( int i = 0, n = e - s; i < n; i++ ) {
            int k = s + i;
            if ( ( k >= 0 ) && ( k < nc ) ) {
                chf = ca [ s + i ];
                clf = BidiClassUtils.getBidiClass ( chf );
                if ( clf != BidiConstants.NSM ) {
                    break;
                }
            }
        }
        if ( clf != BidiConstants.AL ) {
            return false;
        }
        int chl = 0;    // last non-NSM char in [s,e)
        int cll = 0;
        for ( int i = 0, n = e - s; i < n; i++ ) {
            int k = n - i - 1;
            int j = s + k;
            if ( ( j >= 0 ) && ( j < nc ) ) {
                chl = ca [ j ];
                cll = BidiClassUtils.getBidiClass ( chl );
                if ( cll != BidiConstants.NSM ) {
                    break;
                }
            }
        }
        if ( cll != BidiConstants.AL ) {
            return false;
        }
        if ( hasIsolateFinal ( chf ) ) {
            return false;
        } else if ( hasIsolateInitial ( chl ) ) {
            return false;
        } else {
            return true;
        }
    }

    private static boolean hasMedialFollowingContext ( int[] ca, int nc, int s, int e ) {
        int chf = 0;
        int clf = 0;
        for ( int i = e, n = nc; i < n; i++ ) {
            chf = ca [ i ];
            clf = BidiClassUtils.getBidiClass ( chf );
            if ( clf != BidiConstants.NSM ) {
                break;
            }
        }
        if ( clf != BidiConstants.AL ) {
            return false;
        } else if ( hasIsolateFinal ( chf ) ) {
            return false;
        } else {
            return true;
        }
    }

    private static boolean hasLigaturePrecedingContext ( int[] ca, int nc, int s, int e ) {
        return true;
    }

    private static boolean hasLigatureFollowingContext ( int[] ca, int nc, int s, int e ) {
        int chf = 0;
        int clf = 0;
        for ( int i = e, n = nc; i < n; i++ ) {
            chf = ca [ i ];
            clf = BidiClassUtils.getBidiClass ( chf );
            if ( clf != BidiConstants.NSM ) {
                break;
            }
        }
        if ( clf == BidiConstants.AL ) {
            return true;
        } else  {
            return false;
        }
    }

    /**
     * Ordered array of Unicode scalars designating those Arabic (Script) Letters
     * which exhibit an isolated form in word initial position.
     */
    private static int[] isolatedInitials = {
        0x0621, // HAMZA
        0x0622, // ALEF WITH MADDA ABOVE
        0x0623, // ALEF WITH HAMZA ABOVE
        0x0624, // WAW WITH HAMZA ABOVE
        0x0625, // ALEF WITH HAMZA BELOWW
        0x0627, // ALEF
        0x062F, // DAL
        0x0630, // THAL
        0x0631, // REH
        0x0632, // ZAIN
        0x0648, // WAW
        0x0671, // ALEF WASLA
        0x0672, // ALEF WITH WAVY HAMZA ABOVE
        0x0673, // ALEF WITH WAVY HAMZA BELOW
        0x0675, // HIGH HAMZA ALEF
        0x0676, // HIGH HAMZA WAW
        0x0677, // U WITH HAMZA ABOVE
        0x0688, // DDAL
        0x0689, // DAL WITH RING
        0x068A, // DAL WITH DOT BELOW
        0x068B, // DAL WITH DOT BELOW AND SMALL TAH
        0x068C, // DAHAL
        0x068D, // DDAHAL
        0x068E, // DUL
        0x068F, // DUL WITH THREE DOTS ABOVE DOWNWARDS
        0x0690, // DUL WITH FOUR DOTS ABOVE
        0x0691, // RREH
        0x0692, // REH WITH SMALL V
        0x0693, // REH WITH RING
        0x0694, // REH WITH DOT BELOW
        0x0695, // REH WITH SMALL V BELOW
        0x0696, // REH WITH DOT BELOW AND DOT ABOVE
        0x0697, // REH WITH TWO DOTS ABOVE
        0x0698, // JEH
        0x0699, // REH WITH FOUR DOTS ABOVE
        0x06C4, // WAW WITH RING
        0x06C5, // KIRGHIZ OE
        0x06C6, // OE
        0x06C7, // U
        0x06C8, // YU
        0x06C9, // KIRGHIZ YU
        0x06CA, // WAW WITH TWO DOTS ABOVE
        0x06CB, // VE
        0x06CF, // WAW WITH DOT ABOVE
        0x06EE, // DAL WITH INVERTED V
        0x06EF  // REH WITH INVERTED V
    };

    private static boolean hasIsolateInitial ( int ch ) {
        return Arrays.binarySearch ( isolatedInitials, ch ) >= 0;
    }

    /**
     * Ordered array of Unicode scalars designating those Arabic (Script) Letters
     * which exhibit an isolated form in word final position.
     */
    private static int[] isolatedFinals = {
        0x0621  // HAMZA
    };

    private static boolean hasIsolateFinal ( int ch ) {
        return Arrays.binarySearch ( isolatedFinals, ch ) >= 0;
    }

}
