/* ====================================================================
   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.hssf.record.aggregates;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.model.RecordStream;
import org.apache.poi.hssf.model.InternalSheet;
import org.apache.poi.hssf.record.*;
import org.apache.poi.util.HexDump;

/**
 * Groups the page settings records for a worksheet.<p>
 *
 * See OOO excelfileformat.pdf sec 4.4 'Page Settings Block'
 */
public final class PageSettingsBlock extends RecordAggregate {

    /**
     * PLS is potentially a <i>continued</i> record, but is currently uninterpreted by POI
     */
    private static final class PLSAggregate extends RecordAggregate {
        private static final ContinueRecord[] EMPTY_CONTINUE_RECORD_ARRAY = { };
        private final Record _pls;
        /**
         * holds any continue records found after the PLS record.<br/>
         * This would not be required if PLS was properly interpreted.
         * Currently, PLS is an {@link UnknownRecord} and does not automatically
         * include any trailing {@link ContinueRecord}s.
         */
        private ContinueRecord[] _plsContinues;

        public PLSAggregate(RecordStream rs) {
            _pls = rs.getNext();
            if (rs.peekNextSid()==ContinueRecord.sid) {
                List<ContinueRecord> temp = new ArrayList<ContinueRecord>();
                while (rs.peekNextSid()==ContinueRecord.sid) {
                    temp.add((ContinueRecord)rs.getNext());
                }
                _plsContinues = new ContinueRecord[temp.size()];
                temp.toArray(_plsContinues);
            } else {
                _plsContinues = EMPTY_CONTINUE_RECORD_ARRAY;
            }
        }

        @Override
        public void visitContainedRecords(RecordVisitor rv) {
            rv.visitRecord(_pls);
            for (ContinueRecord _plsContinue : _plsContinues) {
                rv.visitRecord(_plsContinue);
            }
        }
    }

    // Every one of these component records is optional
    // (The whole PageSettingsBlock may not be present)
    private PageBreakRecord _rowBreaksRecord;
    private PageBreakRecord _columnBreaksRecord;
    private HeaderRecord _header;
    private FooterRecord _footer;
    private HCenterRecord _hCenter;
    private VCenterRecord _vCenter;
    private LeftMarginRecord _leftMargin;
    private RightMarginRecord _rightMargin;
    private TopMarginRecord _topMargin;
    private BottomMarginRecord _bottomMargin;
    private final List<PLSAggregate> _plsRecords;
    private PrintSetupRecord _printSetup;
    private Record _bitmap;
    private HeaderFooterRecord _headerFooter;
    /**
     * HeaderFooterRecord records belonging to preceding CustomViewSettingsRecordAggregates.
     * The indicator of such records is a non-zero GUID,
     *  see {@link  org.apache.poi.hssf.record.HeaderFooterRecord#getGuid()}
     */
    private final List<HeaderFooterRecord> _sviewHeaderFooters = new ArrayList<HeaderFooterRecord>();
    private Record _printSize;

    public PageSettingsBlock(RecordStream rs) {
        _plsRecords = new ArrayList<PLSAggregate>();
        while(true) {
            if (!readARecord(rs)) {
                break;
            }
        }
    }

    /**
     * Creates a PageSettingsBlock with default settings
     */
    public PageSettingsBlock() {
        _plsRecords = new ArrayList<PLSAggregate>();
        _rowBreaksRecord = new HorizontalPageBreakRecord();
        _columnBreaksRecord = new VerticalPageBreakRecord();
        _header = new HeaderRecord("");
        _footer = new FooterRecord("");
        _hCenter = createHCenter();
        _vCenter = createVCenter();
        _printSetup = createPrintSetup();
    }

    /**
     * @param sid the record sid
     * 
     * @return <code>true</code> if the specified Record sid is one belonging to the
     * 'Page Settings Block'.
     */
    public static boolean isComponentRecord(int sid) {
        switch (sid) {
            case HorizontalPageBreakRecord.sid:
            case VerticalPageBreakRecord.sid:
            case HeaderRecord.sid:
            case FooterRecord.sid:
            case HCenterRecord.sid:
            case VCenterRecord.sid:
            case LeftMarginRecord.sid:
            case RightMarginRecord.sid:
            case TopMarginRecord.sid:
            case BottomMarginRecord.sid:
            case UnknownRecord.PLS_004D:
            case PrintSetupRecord.sid:
            case UnknownRecord.BITMAP_00E9:
            case UnknownRecord.PRINTSIZE_0033:
            case HeaderFooterRecord.sid: // extra header/footer settings supported by Excel 2007
                return true;
        }
        return false;
    }

    private boolean readARecord(RecordStream rs) {
        switch (rs.peekNextSid()) {
            case HorizontalPageBreakRecord.sid:
                checkNotPresent(_rowBreaksRecord);
                _rowBreaksRecord = (PageBreakRecord) rs.getNext();
                break;
            case VerticalPageBreakRecord.sid:
                checkNotPresent(_columnBreaksRecord);
                _columnBreaksRecord = (PageBreakRecord) rs.getNext();
                break;
            case HeaderRecord.sid:
                checkNotPresent(_header);
                _header = (HeaderRecord) rs.getNext();
                break;
            case FooterRecord.sid:
                checkNotPresent(_footer);
                _footer = (FooterRecord) rs.getNext();
                break;
            case HCenterRecord.sid:
                checkNotPresent(_hCenter);
                _hCenter = (HCenterRecord) rs.getNext();
                break;
            case VCenterRecord.sid:
                checkNotPresent(_vCenter);
                _vCenter = (VCenterRecord) rs.getNext();
                break;
            case LeftMarginRecord.sid:
                checkNotPresent(_leftMargin);
                _leftMargin = (LeftMarginRecord) rs.getNext();
                break;
            case RightMarginRecord.sid:
                checkNotPresent(_rightMargin);
                _rightMargin = (RightMarginRecord) rs.getNext();
                break;
            case TopMarginRecord.sid:
                checkNotPresent(_topMargin);
                _topMargin = (TopMarginRecord) rs.getNext();
                break;
            case BottomMarginRecord.sid:
                checkNotPresent(_bottomMargin);
                _bottomMargin = (BottomMarginRecord) rs.getNext();
                break;
            case UnknownRecord.PLS_004D:
                _plsRecords.add(new PLSAggregate(rs));
                break;
            case PrintSetupRecord.sid:
                checkNotPresent(_printSetup);
                _printSetup = (PrintSetupRecord)rs.getNext();
                break;
            case UnknownRecord.BITMAP_00E9:
                checkNotPresent(_bitmap);
                _bitmap = rs.getNext();
                break;
            case UnknownRecord.PRINTSIZE_0033:
                checkNotPresent(_printSize);
                _printSize = rs.getNext();
                break;
            case HeaderFooterRecord.sid:
                //there can be multiple HeaderFooterRecord records belonging to different sheet views
                HeaderFooterRecord hf = (HeaderFooterRecord)rs.getNext();
                if(hf.isCurrentSheet()) {
                    _headerFooter = hf;
                } else {
                    _sviewHeaderFooters.add(hf);
                }
                break;
            default:
                // all other record types are not part of the PageSettingsBlock
                return false;
        }
        return true;
    }

    private void checkNotPresent(Record rec) {
        if (rec != null) {
            throw new RecordFormatException("Duplicate PageSettingsBlock record (sid=0x"
                    + Integer.toHexString(rec.getSid()) + ")");
        }
    }

    private PageBreakRecord getRowBreaksRecord() {
        if (_rowBreaksRecord == null) {
            _rowBreaksRecord = new HorizontalPageBreakRecord();
        }
        return _rowBreaksRecord;
    }

    private PageBreakRecord getColumnBreaksRecord() {
        if (_columnBreaksRecord == null) {
            _columnBreaksRecord = new VerticalPageBreakRecord();
        }
        return _columnBreaksRecord;
    }


    /**
     * Sets a page break at the indicated column
     *
     * @param column the column to add page breaks to
     * @param fromRow the starting row
     * @param toRow the ending row
     */
    public void setColumnBreak(short column, short fromRow, short toRow) {
        getColumnBreaksRecord().addBreak(column, fromRow, toRow);
    }

    /**
     * Removes a page break at the indicated column
     *
     * @param column the column to check for page breaks
     */
    public void removeColumnBreak(int column) {
        getColumnBreaksRecord().removeBreak(column);
    }




    @Override
    public void visitContainedRecords(RecordVisitor rv) {
        // Replicates record order from Excel 2007, though this is not critical

        visitIfPresent(_rowBreaksRecord, rv);
        visitIfPresent(_columnBreaksRecord, rv);
        // Write out empty header / footer records if these are missing
        if (_header == null) {
            rv.visitRecord(new HeaderRecord(""));
        } else {
            rv.visitRecord(_header);
        }
        if (_footer == null) {
            rv.visitRecord(new FooterRecord(""));
        } else {
            rv.visitRecord(_footer);
        }
        visitIfPresent(_hCenter, rv);
        visitIfPresent(_vCenter, rv);
        visitIfPresent(_leftMargin, rv);
        visitIfPresent(_rightMargin, rv);
        visitIfPresent(_topMargin, rv);
        visitIfPresent(_bottomMargin, rv);
        for (RecordAggregate pls : _plsRecords) {
            pls.visitContainedRecords(rv);
        }
        visitIfPresent(_printSetup, rv);
        visitIfPresent(_printSize, rv);
        visitIfPresent(_headerFooter, rv);
        visitIfPresent(_bitmap, rv);
    }
    private static void visitIfPresent(Record r, RecordVisitor rv) {
        if (r != null) {
            rv.visitRecord(r);
        }
    }
    private static void visitIfPresent(PageBreakRecord r, RecordVisitor rv) {
        if (r != null) {
            if (r.isEmpty()) {
                // its OK to not serialize empty page break records
                return;
            }
            rv.visitRecord(r);
        }
    }

    /**
     * creates the HCenter Record and sets it to false (don't horizontally center)
     */
    private static HCenterRecord createHCenter() {
        HCenterRecord retval = new HCenterRecord();

        retval.setHCenter(false);
        return retval;
    }

    /**
     * creates the VCenter Record and sets it to false (don't horizontally center)
     */
    private static VCenterRecord createVCenter() {
        VCenterRecord retval = new VCenterRecord();

        retval.setVCenter(false);
        return retval;
    }

    /**
     * creates the PrintSetup Record and sets it to defaults and marks it invalid
     * @see org.apache.poi.hssf.record.PrintSetupRecord
     * @see org.apache.poi.hssf.record.Record
     * @return record containing a PrintSetupRecord
     */
    private static PrintSetupRecord createPrintSetup() {
        PrintSetupRecord retval = new PrintSetupRecord();

        retval.setPaperSize(( short ) 1);
        retval.setScale(( short ) 100);
        retval.setPageStart(( short ) 1);
        retval.setFitWidth(( short ) 1);
        retval.setFitHeight(( short ) 1);
        retval.setOptions(( short ) 2);
        retval.setHResolution(( short ) 300);
        retval.setVResolution(( short ) 300);
        retval.setHeaderMargin( 0.5);
        retval.setFooterMargin( 0.5);
        retval.setCopies(( short ) 1);
        return retval;
    }


    /**
     * Returns the HeaderRecord.
     * @return HeaderRecord for the sheet.
     */
    public HeaderRecord getHeader ()
    {
        return _header;
    }

    /**
     * Sets the HeaderRecord.
     * @param newHeader The new HeaderRecord for the sheet.
     */
    public void setHeader (HeaderRecord newHeader)
    {
        _header = newHeader;
    }

    /**
     * Returns the FooterRecord.
     * @return FooterRecord for the sheet.
     */
    public FooterRecord getFooter ()
    {
        return _footer;
    }

    /**
     * Sets the FooterRecord.
     * @param newFooter The new FooterRecord for the sheet.
     */
    public void setFooter (FooterRecord newFooter)
    {
        _footer = newFooter;
    }

    /**
     * Returns the PrintSetupRecord.
     * @return PrintSetupRecord for the sheet.
     */
    public PrintSetupRecord getPrintSetup ()
    {
        return _printSetup;
    }

    /**
     * Sets the PrintSetupRecord.
     * @param newPrintSetup The new PrintSetupRecord for the sheet.
     */
    public void setPrintSetup (PrintSetupRecord newPrintSetup)
    {
        _printSetup = newPrintSetup;
    }


    private Margin getMarginRec(int marginIndex) {
        switch (marginIndex) {
            case InternalSheet.LeftMargin:   return _leftMargin;
            case InternalSheet.RightMargin:  return _rightMargin;
            case InternalSheet.TopMargin:    return _topMargin;
            case InternalSheet.BottomMargin: return _bottomMargin;
        }
        throw new IllegalArgumentException( "Unknown margin constant:  " + marginIndex );
    }


    /**
     * Gets the size of the margin in inches.
     * @param margin which margin to get
     * @return the size of the margin
     */
    public double getMargin(short margin) {
        Margin m = getMarginRec(margin);
        if (m != null) {
            return m.getMargin();
        }
        switch (margin) {
            case InternalSheet.LeftMargin:   return .75;
            case InternalSheet.RightMargin:  return .75;
            case InternalSheet.TopMargin:    return 1.0;
            case InternalSheet.BottomMargin: return 1.0;
        }
        throw new IllegalArgumentException( "Unknown margin constant:  " + margin );
    }

    /**
     * Sets the size of the margin in inches.
     * @param margin which margin to get
     * @param size the size of the margin
     */
    public void setMargin(short margin, double size) {
        Margin m = getMarginRec(margin);
        if (m  == null) {
            switch (margin) {
                case InternalSheet.LeftMargin:
                    _leftMargin = new LeftMarginRecord();
                    m = _leftMargin;
                    break;
                case InternalSheet.RightMargin:
                    _rightMargin = new RightMarginRecord();
                    m = _rightMargin;
                    break;
                case InternalSheet.TopMargin:
                    _topMargin = new TopMarginRecord();
                    m = _topMargin;
                    break;
                case InternalSheet.BottomMargin:
                    _bottomMargin = new BottomMarginRecord();
                    m = _bottomMargin;
                    break;
                default :
                    throw new IllegalArgumentException( "Unknown margin constant:  " + margin );
            }
        }
        m.setMargin( size );
    }

    /**
     * Shifts all the page breaks in the range "count" number of rows/columns
     * @param breaks The page record to be shifted
     * @param start Starting "main" value to shift breaks
     * @param stop Ending "main" value to shift breaks
     * @param count number of units (rows/columns) to shift by
     */
    private static void shiftBreaks(PageBreakRecord breaks, int start, int stop, int count) {

        Iterator<PageBreakRecord.Break> iterator = breaks.getBreaksIterator();
        List<PageBreakRecord.Break> shiftedBreak = new ArrayList<PageBreakRecord.Break>();
        while(iterator.hasNext())
        {
            PageBreakRecord.Break breakItem = iterator.next();
            int breakLocation = breakItem.main;
            boolean inStart = (breakLocation >= start);
            boolean inEnd = (breakLocation <= stop);
            if(inStart && inEnd) {
                shiftedBreak.add(breakItem);
            }
        }

        iterator = shiftedBreak.iterator();
        while (iterator.hasNext()) {
            PageBreakRecord.Break breakItem = iterator.next();
            breaks.removeBreak(breakItem.main);
            breaks.addBreak((short)(breakItem.main+count), breakItem.subFrom, breakItem.subTo);
        }
    }


    /**
     * Sets a page break at the indicated row
     * @param row the row
     * @param fromCol the starting column
     * @param toCol the ending column
     */
    public void setRowBreak(int row, short fromCol, short toCol) {
        getRowBreaksRecord().addBreak((short)row, fromCol, toCol);
    }

    /**
     * Removes a page break at the indicated row
     * @param row the row
     */
    public void removeRowBreak(int row) {
        if (getRowBreaksRecord().getBreaks().length < 1) {
            throw new IllegalArgumentException("Sheet does not define any row breaks");
        }
        getRowBreaksRecord().removeBreak((short)row);
    }

    /**
     * Queries if the specified row has a page break
     * 
     * @param row the row to check for
     * 
     * @return true if the specified row has a page break
     */
    public boolean isRowBroken(int row) {
        return getRowBreaksRecord().getBreak(row) != null;
    }


    /**
     * Queries if the specified column has a page break
     * 
     * @param column the column to check for
     *
     * @return <code>true</code> if the specified column has a page break
     */
    public boolean isColumnBroken(int column) {
        return getColumnBreaksRecord().getBreak(column) != null;
    }

    /**
     * Shifts the horizontal page breaks for the indicated count
     * @param startingRow the starting row
     * @param endingRow the ending row
     * @param count the number of rows to shift by
     */
    public void shiftRowBreaks(int startingRow, int endingRow, int count) {
        shiftBreaks(getRowBreaksRecord(), startingRow, endingRow, count);
    }

    /**
     * Shifts the vertical page breaks for the indicated count
     * @param startingCol the starting column
     * @param endingCol the ending column
     * @param count the number of columns to shift by
     */
    public void shiftColumnBreaks(short startingCol, short endingCol, short count) {
        shiftBreaks(getColumnBreaksRecord(), startingCol, endingCol, count);
    }

    /**
     * @return all the horizontal page breaks, never <code>null</code>
     */
    public int[] getRowBreaks() {
        return getRowBreaksRecord().getBreaks();
    }

    /**
     * @return the number of row page breaks
     */
    public int getNumRowBreaks(){
        return getRowBreaksRecord().getNumBreaks();
    }

    /**
     * @return all the column page breaks, never <code>null</code>
     */
    public int[] getColumnBreaks(){
        return getColumnBreaksRecord().getBreaks();
    }

    /**
     * @return the number of column page breaks
     */
    public int getNumColumnBreaks(){
        return getColumnBreaksRecord().getNumBreaks();
    }

    public VCenterRecord getVCenter() {
        return _vCenter;
    }

    public HCenterRecord getHCenter() {
        return _hCenter;
    }

    /**
     * HEADERFOOTER is new in 2007.  Some apps seem to have scattered this record long after
     * the {@link PageSettingsBlock} where it belongs.
     * 
     * @param rec the HeaderFooterRecord to set
     */
    public void addLateHeaderFooter(HeaderFooterRecord rec) {
        if (_headerFooter != null) {
            throw new IllegalStateException("This page settings block already has a header/footer record");
        }
        if (rec.getSid() != HeaderFooterRecord.sid) {
            throw new RecordFormatException("Unexpected header-footer record sid: 0x" + Integer.toHexString(rec.getSid()));
        }
        _headerFooter = rec;
    }

    /**
     * This method reads PageSettingsBlock records from the supplied RecordStream until the first
     * non-PageSettingsBlock record is encountered.  As each record is read, it is incorporated
     * into this PageSettingsBlock.<p>
     * 
     * The latest Excel version seems to write the PageSettingsBlock uninterrupted. However there
     * are several examples (that Excel reads OK) where these records are not written together:
     * 
     * <ul>
     * <li><b>HEADER_FOOTER(0x089C) after WINDOW2</b> - This record is new in 2007.  Some apps
     * seem to have scattered this record long after the PageSettingsBlock where it belongs
     * test samples: SharedFormulaTest.xls, ex44921-21902.xls, ex42570-20305.xls</li>
     * <li><b>PLS, WSBOOL, PageSettingsBlock</b> - WSBOOL is not a PSB record.
     * This happens in the test sample file "NoGutsRecords.xls" and "WORKBOOK_in_capitals.xls"</li>
     * <li><b>Margins after DIMENSION</b> - All of PSB should be before DIMENSION. (Bug-47199)</li>
     * </ul>
     * 
     * These were probably written by other applications (or earlier versions of Excel). It was
     * decided to not write specific code for detecting each of these cases.  POI now tolerates
     * PageSettingsBlock records scattered all over the sheet record stream, and in any order, but
     * does not allow duplicates of any of those records.<p>
     *
     * <b>Note</b> - when POI writes out this PageSettingsBlock, the records will always be written
     * in one consolidated block (in the standard ordering) regardless of how scattered the records
     * were when they were originally read.
     *
     * @param rs the RecordStream to read from
     * 
     * @throws  RecordFormatException if any PSB record encountered has the same type (sid) as
     * a record that is already part of this PageSettingsBlock
     */
    public void addLateRecords(RecordStream rs) {
        while(true) {
            if (!readARecord(rs)) {
                break;
            }
        }
    }

    /**
     * Some apps can define multiple HeaderFooterRecord records for a sheet.
     * When saving such a file Excel 2007 re-positions them according to the following rules:
     *  - take a HeaderFooterRecord and read 16-byte GUID at offset 12. If it is zero,
     *    it means the current sheet and the given HeaderFooterRecord belongs to this PageSettingsBlock
     *  - If GUID is not zero then search in preceding CustomViewSettingsRecordAggregates.
     *    Compare first 16 bytes of UserSViewBegin with the HeaderFooterRecord's GUID. If match,
     *    then append the HeaderFooterRecord to this CustomViewSettingsRecordAggregates
     *
     * @param sheetRecords the list of sheet records read so far
     */
    public void positionRecords(List<RecordBase> sheetRecords) {
        // Take a copy to loop over, so we can update the real one
        //  without concurrency issues
        List<HeaderFooterRecord> hfRecordsToIterate = new ArrayList<HeaderFooterRecord>(_sviewHeaderFooters);

        final Map<String, HeaderFooterRecord> hfGuidMap = new HashMap<String, HeaderFooterRecord>();

        for(final HeaderFooterRecord hf : hfRecordsToIterate) {
            hfGuidMap.put(HexDump.toHex(hf.getGuid()), hf);
        }

        // loop through HeaderFooterRecord records having not-empty GUID and match them with
        // CustomViewSettingsRecordAggregate blocks having UserSViewBegin with the same GUID
        for (RecordBase rb : sheetRecords) {
            if (rb instanceof CustomViewSettingsRecordAggregate) {
                final CustomViewSettingsRecordAggregate cv = (CustomViewSettingsRecordAggregate) rb;
                cv.visitContainedRecords(new RecordVisitor() {
                    @Override
                    public void visitRecord(Record r) {
                        if (r.getSid() == UserSViewBegin.sid) {
                            String guid = HexDump.toHex(((UserSViewBegin) r).getGuid());
                            HeaderFooterRecord hf = hfGuidMap.get(guid);

                            if (hf != null) {
                                cv.append(hf);
                                _sviewHeaderFooters.remove(hf);
                            }
                        }
                    }
                });
            }
        }
    }
}
