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

import org.apache.poi.hwpf.usermodel.BorderCode;
import org.apache.poi.hwpf.usermodel.TableCellDescriptor;
import org.apache.poi.hwpf.usermodel.TableProperties;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;

@Internal
public final class TableSprmUncompressor
  extends SprmUncompressor
{
  private static final POILogger logger = POILogFactory.getLogger( TableSprmUncompressor.class );

  public TableSprmUncompressor()
  {
  }

    public static TableProperties uncompressTAP( SprmBuffer sprmBuffer )
    {
        TableProperties tableProperties;

        SprmOperation sprmOperation = sprmBuffer.findSprm( (short) 0xd608 );
        if ( sprmOperation != null )
        {
            byte[] grpprl = sprmOperation.getGrpprl();
            int offset = sprmOperation.getGrpprlOffset();
            short itcMac = grpprl[offset];
            tableProperties = new TableProperties( itcMac );
        }
        else
        {
            logger.log( POILogger.WARN,
                    "Some table rows didn't specify number of columns in SPRMs" );
            tableProperties = new TableProperties( (short) 1 );
        }

        for ( SprmIterator iterator = sprmBuffer.iterator(); iterator.hasNext(); )
        {
            SprmOperation sprm = iterator.next();

            /*
             * TAPXs are actually PAPXs so we have to make sure we are only
             * trying to uncompress the right type of sprm.
             */
            if ( sprm.getType() == SprmOperation.TYPE_TAP )
            {
                try
                {
                    unCompressTAPOperation( tableProperties, sprm );
                }
                catch ( ArrayIndexOutOfBoundsException ex )
                {
                    logger.log( POILogger.ERROR, "Unable to apply ", sprm,
                            ": ", ex, ex );
                }
            }
        }
        return tableProperties;
    }

  /**
   * Used to uncompress a table property. Performs an operation defined
   * by a sprm stored in a tapx.
   *
   * @param newTAP The TableProperties object to perform the operation on.
   * @param operand The operand that defines this operation.
   * @param param The parameter for this operation.
   * @param varParam Variable length parameter for this operation.
   */
  static void unCompressTAPOperation (TableProperties newTAP, SprmOperation sprm)
  {
    switch (sprm.getOperation())
    {
      case 0:
        newTAP.setJc ((short) sprm.getOperand());
        break;
      case 0x01:
      {
        short[] rgdxaCenter = newTAP.getRgdxaCenter ();
        short itcMac = newTAP.getItcMac ();
        int adjust = sprm.getOperand() - (rgdxaCenter[0] + newTAP.getDxaGapHalf ());
        for (int x = 0; x < itcMac; x++)
        {
          rgdxaCenter[x] += adjust;
        }
        break;
      }
      case 0x02:
      {
        short[] rgdxaCenter = newTAP.getRgdxaCenter ();
        if (rgdxaCenter != null)
        {
          int adjust = newTAP.getDxaGapHalf () - sprm.getOperand();
          rgdxaCenter[0] += adjust;
        }
        newTAP.setDxaGapHalf (sprm.getOperand());
        break;
      }
      case 0x03:
        newTAP.setFCantSplit (getFlag(sprm.getOperand()));
        break;
      case 0x04:
        newTAP.setFTableHeader (getFlag (sprm.getOperand()));
        break;
      case 0x05:
      {
        byte[] buf = sprm.getGrpprl();
        int offset = sprm.getGrpprlOffset();
        newTAP.setBrcTop(new BorderCode(buf, offset));
        offset += BorderCode.SIZE;
        newTAP.setBrcLeft(new BorderCode(buf, offset));
        offset += BorderCode.SIZE;
        newTAP.setBrcBottom(new BorderCode(buf, offset));
        offset += BorderCode.SIZE;
        newTAP.setBrcRight(new BorderCode(buf, offset));
        offset += BorderCode.SIZE;
        newTAP.setBrcHorizontal(new BorderCode(buf, offset));
        offset += BorderCode.SIZE;
        newTAP.setBrcVertical(new BorderCode(buf, offset));
        break;
      }
      case 0x06:

        //obsolete, used in word 1.x
        break;
      case 0x07:
        newTAP.setDyaRowHeight (sprm.getOperand());
        break;
      case 0x08:
      {
        byte[] grpprl = sprm.getGrpprl();
        int offset = sprm.getGrpprlOffset();
        short itcMac = grpprl[offset];
        short[] rgdxaCenter = new short[itcMac + 1];
        TableCellDescriptor[] rgtc = new TableCellDescriptor[itcMac];
        //I use varParam[0] and newTAP._itcMac interchangably
        newTAP.setItcMac (itcMac);
        newTAP.setRgdxaCenter (rgdxaCenter);
        newTAP.setRgtc (rgtc);

        // get the rgdxaCenters
        for (int x = 0; x < itcMac; x++)
        {
          rgdxaCenter[x] = LittleEndian.getShort (grpprl, offset + (1 + (x * 2)));
        }

        // only try to get the TC entries if they exist...
        int endOfSprm = offset+sprm.size()-6; // -2 bytes for sprm - 2 for size short - 2 to correct offsets being 0 based
        int startOfTCs = offset + (1 + (itcMac + 1) * 2);

        boolean hasTCs = startOfTCs < endOfSprm;

        for (int x = 0; x < itcMac; x++)
        {
          // Sometimes, the grpprl does not contain data at every offset. I have no idea why this happens.
          if(hasTCs && offset + (1 + ( (itcMac + 1) * 2) + (x * 20)) < grpprl.length)
            rgtc[x] = TableCellDescriptor.convertBytesToTC(grpprl,
               offset + (1 + ( (itcMac + 1) * 2) + (x * 20)));
          else
            rgtc[x] = new TableCellDescriptor();
        }

        rgdxaCenter[itcMac] = LittleEndian.getShort (grpprl, offset + (1 + (itcMac * 2)));
        break;
      }
      case 0x09:

        /** @todo handle cell shading*/
        break;
      case 0x0a:

        /** @todo handle word defined table styles*/
        break;
      case 0x20:
//      {
//        TableCellDescriptor[] rgtc = newTAP.getRgtc();
//
//        for (int x = varParam[0]; x < varParam[1]; x++)
//        {
//
//          if ((varParam[2] & 0x08) > 0)
//          {
//            short[] brcRight = rgtc[x].getBrcRight ();
//            brcRight[0] = LittleEndian.getShort (varParam, 6);
//            brcRight[1] = LittleEndian.getShort (varParam, 8);
//          }
//          else if ((varParam[2] & 0x04) > 0)
//          {
//            short[] brcBottom = rgtc[x].getBrcBottom ();
//            brcBottom[0] = LittleEndian.getShort (varParam, 6);
//            brcBottom[1] = LittleEndian.getShort (varParam, 8);
//          }
//          else if ((varParam[2] & 0x02) > 0)
//          {
//            short[] brcLeft = rgtc[x].getBrcLeft ();
//            brcLeft[0] = LittleEndian.getShort (varParam, 6);
//            brcLeft[1] = LittleEndian.getShort (varParam, 8);
//          }
//          else if ((varParam[2] & 0x01) > 0)
//          {
//            short[] brcTop = rgtc[x].getBrcTop ();
//            brcTop[0] = LittleEndian.getShort (varParam, 6);
//            brcTop[1] = LittleEndian.getShort (varParam, 8);
//          }
//        }
//        break;
//      }
        break;
      case 0x21:
      {
        int param = sprm.getOperand();
        int index = (param & 0xff000000) >> 24;
        int count = (param & 0x00ff0000) >> 16;
        int width = (param & 0x0000ffff);
        int itcMac = newTAP.getItcMac();

        short[] rgdxaCenter = new short[itcMac + count + 1];
        TableCellDescriptor[] rgtc = new TableCellDescriptor[itcMac + count];
        if (index >= itcMac)
        {
          index = itcMac;
          System.arraycopy(newTAP.getRgdxaCenter(), 0, rgdxaCenter, 0,
                           itcMac + 1);
          System.arraycopy(newTAP.getRgtc(), 0, rgtc, 0, itcMac);
        }
        else
        {
          //copy rgdxaCenter
          System.arraycopy(newTAP.getRgdxaCenter(), 0, rgdxaCenter, 0,
                           index + 1);
          System.arraycopy(newTAP.getRgdxaCenter(), index + 1, rgdxaCenter,
                           index + count, itcMac - (index));
          //copy rgtc
          System.arraycopy(newTAP.getRgtc(), 0, rgtc, 0, index);
          System.arraycopy(newTAP.getRgtc(), index, rgtc, index + count,
                           itcMac - index);
        }

        for (int x = index; x < index + count; x++)
        {
          rgtc[x] = new TableCellDescriptor();
          rgdxaCenter[x] = (short)(rgdxaCenter[x - 1] + width);
        }
        rgdxaCenter[index +
          count] = (short)(rgdxaCenter[(index + count) - 1] + width);
        break;
      }
      /**@todo handle table sprms from complex files*/
      case 0x22:
      case 0x23:
      case 0x24:
      case 0x25:
      case 0x26:
      case 0x27:
      case 0x28:
      case 0x29:
      case 0x2a:
      case 0x2b:
      case 0x2c:
        break;
      case 0x34:
        // sprmTCellPaddingDefault -- (0xd634)
        // TODO: extract into CSSA structure
        byte itcFirst = sprm.getGrpprl()[sprm.getGrpprlOffset()];
        byte itcLim = sprm.getGrpprl()[sprm.getGrpprlOffset() + 1];
        byte grfbrc = sprm.getGrpprl()[sprm.getGrpprlOffset() + 2];
        byte ftsWidth = sprm.getGrpprl()[sprm.getGrpprlOffset() + 3];
        short wWidth = LittleEndian.getShort(sprm.getGrpprl(),
            sprm.getGrpprlOffset() + 4);

        for (int c = itcFirst; c < itcLim; c++) {
          TableCellDescriptor tableCellDescriptor = newTAP.getRgtc()[c];

          if ((grfbrc & 0x01) != 0) {
            tableCellDescriptor.setFtsCellPaddingTop(ftsWidth);
            tableCellDescriptor.setWCellPaddingTop(wWidth);
          }
          if ((grfbrc & 0x02) != 0) {
            tableCellDescriptor.setFtsCellPaddingLeft(ftsWidth);
            tableCellDescriptor.setWCellPaddingLeft(wWidth);
          }
          if ((grfbrc & 0x04) != 0) {
            tableCellDescriptor.setFtsCellPaddingBottom(ftsWidth);
            tableCellDescriptor.setWCellPaddingBottom(wWidth);
          }
          if ((grfbrc & 0x08) != 0) {
            tableCellDescriptor.setFtsCellPaddingRight(ftsWidth);
            tableCellDescriptor.setWCellPaddingRight(wWidth);
          }
        }
        break;
      default:
        break;
    }
  }



}
