/*
 * Copyright 2005 The Apache Software Foundation.
 *
 * Licensed 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.layoutmgr.table;

import org.apache.fop.fo.Constants;
import org.apache.fop.fo.flow.Table;
import org.apache.fop.fo.flow.TableBody;
import org.apache.fop.fo.flow.TableCell;
import org.apache.fop.fo.flow.TableColumn;
import org.apache.fop.fo.flow.TableRow;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground.BorderInfo;

/**
 * Implements the normal "collapse" border model defined in 6.7.10 in XSL 1.0.
 * 
 * TODO Column groups are not yet checked in this algorithm!
 */
public class CollapsingBorderModelEyeCatching extends CollapsingBorderModel {

    public BorderInfo determineWinner(GridUnit currentGridUnit, 
            GridUnit otherGridUnit, int side, int flags) {
        final boolean vertical = isVerticalRelation(side);
        final int otherSide = getOtherSide(side);
        
        //Get cells
        TableCell currentCell = currentGridUnit.getCell();
        TableCell otherCell = null;
        if (otherGridUnit != null) {
            otherCell = otherGridUnit.getCell();
        }
        
        //Get rows
        TableRow currentRow = currentGridUnit.getRow();
        TableRow otherRow = null;
        if (vertical && otherCell != null) {
            otherRow = otherGridUnit.getRow();
        }
        
        //get bodies
        TableBody currentBody = currentGridUnit.getBody();
        TableBody otherBody = null;
        if (otherRow != null) {
            otherBody = otherGridUnit.getBody();
        }

        //get columns
        TableColumn currentColumn = currentGridUnit.getColumn();
        TableColumn otherColumn = null;
        if (otherGridUnit != null) {
            otherColumn = otherGridUnit.getColumn();
        }
        
        //TODO get column groups
        
        //Get table
        Table table = currentGridUnit.getTable();
        
        //----------------------------------------------------------------------
        //We're creating two arrays containing the applicable BorderInfos for
        //each cell in question.
        //0 = cell, 1 = row, 2 = row group (body), 3 = column, 
        //4 = col group (spanned column, see 6.7.3), 5 = table

        BorderInfo[] current = new BorderInfo[6];
        BorderInfo[] other = new BorderInfo[6];
        //cell
        current[0] = currentGridUnit.getOriginalBorderInfoForCell(side);
        if (otherGridUnit != null) {
            other[0] = otherGridUnit.getOriginalBorderInfoForCell(otherSide);
        }
        if ((currentRow != null) 
                && (side == BEFORE 
                    || side == AFTER
                    || (currentGridUnit.getFlag(GridUnit.IN_FIRST_COLUMN) && side == START)
                    || (currentGridUnit.getFlag(GridUnit.IN_LAST_COLUMN) && side == END))) {
            //row
            current[1] = currentRow.getCommonBorderPaddingBackground().getBorderInfo(side);
        }
        if (otherRow != null) {
            //row
            other[1] = otherRow.getCommonBorderPaddingBackground().getBorderInfo(otherSide);
        }
        if ((side == BEFORE && currentGridUnit.getFlag(GridUnit.FIRST_IN_BODY))
                || (side == AFTER && currentGridUnit.getFlag(GridUnit.LAST_IN_BODY))
                || (currentGridUnit.getFlag(GridUnit.IN_FIRST_COLUMN) && side == START)
                || (currentGridUnit.getFlag(GridUnit.IN_LAST_COLUMN) && side == END)) {
            //row group (=body, table-header or table-footer)
            current[2] = currentBody.getCommonBorderPaddingBackground().getBorderInfo(side);
        }
        if (otherGridUnit != null
                && otherBody != null
                && ((otherSide == BEFORE && otherGridUnit.getFlag(GridUnit.FIRST_IN_BODY))
                    || (otherSide == AFTER && otherGridUnit.getFlag(GridUnit.LAST_IN_BODY)))) {
            //row group (=body, table-header or table-footer)
            other[2] = otherBody.getCommonBorderPaddingBackground().getBorderInfo(otherSide);
        }
        if ((side == BEFORE && otherGridUnit == null)
                || (side == AFTER && otherGridUnit == null)
                || (side == START)
                || (side == END)) {
            //column
            current[3] = currentColumn.getCommonBorderPaddingBackground().getBorderInfo(side);
        }
        if (otherColumn != null) {
            //column
            other[3] = otherColumn.getCommonBorderPaddingBackground().getBorderInfo(otherSide);
        }
        //TODO current[4] and other[4] for column groups
        if (otherGridUnit == null
            && ((side == BEFORE && (flags & VERTICAL_START_END_OF_TABLE) > 0)
                    || (side == AFTER && (flags & VERTICAL_START_END_OF_TABLE) > 0)
                    || (side == START)
                    || (side == END))) {
            //table
            current[5] = table.getCommonBorderPaddingBackground().getBorderInfo(side);
        }
        //other[6] is always null, since it's always the same table
        
        BorderInfo resolved = null;
        
        // *** Rule 1 ***
        resolved = doRule1(current, other);
        if (resolved != null) {
            return resolved;
        }
        
        // *** Rule 2 ***
        if (!doRule2(current, other)) {
        }
        
        // *** Rule 3 ***
        resolved = doRule3(current, other);
        if (resolved != null) {
            return resolved;
        }
        
        // *** Rule 4 ***
        resolved = doRule4(current, other);
        if (resolved != null) {
            return resolved;
        }
        
        // *** Rule 5 ***
        resolved = doRule5(current, other);
        if (resolved != null) {
            return resolved;
        }
        
        return null; //no winner, no border
    }

    private BorderInfo doRule1(BorderInfo[] current, BorderInfo[] other) {
        for (int i = 0; i < current.length; i++) {
            if ((current[i] != null) && (current[i].getStyle() == Constants.EN_HIDDEN)) {
                return current[i];
            }
            if ((other[i] != null) && (other[i].getStyle() == Constants.EN_HIDDEN)) {
                return other[i];
            }
        }
        return null;
    }
    
    private boolean doRule2(BorderInfo[] current, BorderInfo[] other) {
        boolean found = false;
        for (int i = 0; i < current.length; i++) {
            if ((current[i] != null) && (current[i].getStyle() != Constants.EN_NONE)) {
                found = true;
                break;
            }
            if ((other[i] != null) && (other[i].getStyle() != Constants.EN_NONE)) {
                found = true;
                break;
            }
        }
        return found;
    }

    private BorderInfo doRule3(BorderInfo[] current, BorderInfo[] other) {
        int width = 0;
        //Find max border width
        for (int i = 0; i < current.length; i++) {
            if ((current[i] != null) && (current[i].getRetainedWidth() > width)) {
                width = current[i].getRetainedWidth();
            }
            if ((other[i] != null) && (other[i].getRetainedWidth() > width)) {
                width = other[i].getRetainedWidth();
            }
        }
        BorderInfo widest = null;
        int count = 0;
        //See if there's only one with the widest border
        for (int i = 0; i < current.length; i++) {
            if ((current[i] != null) && (current[i].getRetainedWidth() == width)) {
                count++;
                if (widest == null) {
                    widest = current[i];
                }
            } else {
                current[i] = null; //Discard the narrower ones
            }
            if ((other[i] != null) && (other[i].getRetainedWidth() == width)) {
                count++;
                if (widest == null) {
                    widest = other[i];
                }
            } else {
                other[i] = null; //Discard the narrower ones
            }
        }
        if (count == 1) {
            return widest;
        } else {
            return null;
        }
    }

    private BorderInfo doRule4(BorderInfo[] current, BorderInfo[] other) {
        int pref = getPreferenceValue(Constants.EN_INSET); //Lowest preference
        //Find highest preference value
        for (int i = 0; i < current.length; i++) {
            if (current[i] != null) {
                int currPref = getPreferenceValue(current[i].getStyle());
                if (currPref > pref) {
                    pref = currPref;
                }
            }
            if (other[i] != null) {
                int currPref = getPreferenceValue(other[i].getStyle());
                if (currPref > pref) {
                    pref = currPref;
                }
            }
        }
        BorderInfo preferred = null;
        int count = 0;
        //See if there's only one with the preferred border style
        for (int i = 0; i < current.length; i++) {
            if (current[i] != null) {
                int currPref = getPreferenceValue(current[i].getStyle());
                if (currPref == pref) {
                    count++;
                    if (preferred == null) {
                        preferred = current[i];
                    }
                    break;
                }
            } else {
                current[i] = null; //Discard the ones that are not preferred
            }
            if (other[i] != null) {
                int currPref = getPreferenceValue(other[i].getStyle());
                if (currPref == pref) {
                    count++;
                    if (preferred == null) {
                        preferred = other[i];
                    }
                    break;
                }
            } else {
                other[i] = null; //Discard the ones that are not preferred
            }
        }
        if (count == 1) {
            return preferred;
        } else {
            return null;
        }
    }

    private BorderInfo doRule5(BorderInfo[] current, BorderInfo[] other) {
        for (int i = 0; i < current.length; i++) {
            if (current[i] != null) {
                return current[i];
            }
            if (other[i] != null) {
                return other[i];
            }
        }
        return null;
    }

}
