/* This file is part of the wvWare 2 project
   SPDX-FileCopyrightText: 2001 S.R.Haque <srhaque@iee.org>
   SPDX-FileCopyrightText: 2003 Werner Trobin <trobin@kde.org>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the Library GNU General Public
   version 2 of the License, or (at your option) version 3 or,
   at the discretion of KDE e.V (which shall act as a proxy as in
   section 14 of the GPLv3), any later version..

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#include "word95_helper.h"
#include "olestream.h"
#include "styles.h"
#include "word95_generated.h"

#include "wvlog.h"

namespace wvWare
{

namespace Word95
{

namespace SPRM
{

typedef enum {
    sprmNoop = 0,
    sprmPIstd = 2,
    sprmPIstdPermute = 3,
    sprmPIncLvl = 4,
    sprmPJc = 5,
    sprmPFSideBySide = 6,
    sprmPFKeep = 7,
    sprmPFKeepFollow = 8,
    sprmPFPageBreakBefore = 9,
    sprmPBrcl = 10,
    sprmPBrcp = 11,
    sprmPAnld = 12,
    sprmPNLvlAnm = 13,
    sprmPFNoLineNumb = 14,
    sprmPChgTabsPapx = 15,
    sprmPDxaRight = 16,
    sprmPDxaLeft = 17,
    sprmPNest = 18,
    sprmPDxaLeft1 = 19,
    sprmPDyaLine = 20,
    sprmPDyaBefore = 21,
    sprmPDyaAfter = 22,
    sprmPChgTabs = 23,
    sprmPFInTable = 24,
    sprmPFTtp = 25,
    sprmPDxaAbs = 26,
    sprmPDyaAbs = 27,
    sprmPDxaWidth = 28,
    sprmPPc = 29,
    sprmPBrcTop10 = 30,
    sprmPBrcLeft10 = 31,
    sprmPBrcBottom10 = 32,
    sprmPBrcRight10 = 33,
    sprmPBrcBetween10 = 34,
    sprmPBrcBar10 = 35,
    sprmPFromText10 = 36,
    sprmPWr = 37,
    sprmPBrcTop = 38,
    sprmPBrcLeft = 39,
    sprmPBrcBottom = 40,
    sprmPBrcRight = 41,
    sprmPBrcBetween = 42,
    sprmPBrcBar = 43,
    sprmPFNoAutoHyph = 44,
    sprmPWHeightAbs = 45,
    sprmPDcs = 46,
    sprmPShd = 47,
    sprmPDyaFromText = 48,
    sprmPDxaFromText = 49,
    sprmPFLocked = 50,
    sprmPFWidowControl = 51,
    sprmPRuler = 52,
    sprmCFStrikeRM = 65,
    sprmCFRMark = 66,
    sprmCFFldVanish = 67,
    sprmCPicLocation = 68,
    sprmCIbstRMark = 69,
    sprmCDttmRMark = 70,
    sprmCFData = 71,
    sprmCRMReason = 72,
    sprmCChse = 73,
    sprmCSymbol = 74,
    sprmCFOle2 = 75,
    sprmCIstd = 80,
    sprmCIstdPermute = 81,
    sprmCDefault = 82,
    sprmCPlain = 83,
    sprmCFBold = 85,
    sprmCFItalic = 86,
    sprmCFStrike = 87,
    sprmCFOutline = 88,
    sprmCFShadow = 89,
    sprmCFSmallCaps = 90,
    sprmCFCaps = 91,
    sprmCFVanish = 92,
    sprmCFtc = 93,
    sprmCKul = 94,
    sprmCSizePos = 95,
    sprmCDxaSpace = 96,
    sprmCLid = 97,
    sprmCIco = 98,
    sprmCHps = 99,
    sprmCHpsInc = 100,
    sprmCHpsPos = 101,
    sprmCHpsPosAdj = 102,
    sprmCMajority = 103,
    sprmCIss = 104,
    sprmCHpsNew50 = 105,
    sprmCHpsInc1 = 106,
    sprmCHpsKern = 107,
    sprmCMajority50 = 108,
    sprmCHpsMul = 109,
    sprmCCondHyhen = 110,
    sprmCFSpec = 117,
    sprmCFObj = 118,
    sprmPicBrcl = 119,
    sprmPicScale = 120,
    sprmPicBrcTop = 121,
    sprmPicBrcLeft = 122,
    sprmPicBrcBottom = 123,
    sprmPicBrcRight = 124,
    sprmSScnsPgn = 131,
    sprmSiHeadingPgn = 132,
    sprmSOlstAnm = 133,
    sprmSDxaColWidth = 136,
    sprmSDxaColSpacing = 137,
    sprmSFEvenlySpaced = 138,
    sprmSFProtected = 139,
    sprmSDmBinFirst = 140,
    sprmSDmBinOther = 141,
    sprmSBkc = 142,
    sprmSFTitlePage = 143,
    sprmSCcolumns = 144,
    sprmSDxaColumns = 145,
    sprmSFAutoPgn = 146,
    sprmSNfcPgn = 147,
    sprmSDyaPgn = 148,
    sprmSDxaPgn = 149,
    sprmSFPgnRestart = 150,
    sprmSFEndnote = 151,
    sprmSLnc = 152,
    sprmSGprfIhdt = 153,
    sprmSNLnnMod = 154,
    sprmSDxaLnn = 155,
    sprmSDyaHdrTop = 156,
    sprmSDyaHdrBottom = 157,
    sprmSLBetween = 158,
    sprmSVjc = 159,
    sprmSLnnMin = 160,
    sprmSPgnStart = 161,
    sprmSBOrientation = 162,
    sprmSBCustomize = 163,
    sprmSXaPage = 164,
    sprmSYaPage = 165,
    sprmSDxaLeft = 166,
    sprmSDxaRight = 167,
    sprmSDyaTop = 168,
    sprmSDyaBottom = 169,
    sprmSDzaGutter = 170,
    sprmSDMPaperReq = 171,
    sprmTJc = 182,
    sprmTDxaLeft = 183,
    sprmTDxaGapHalf = 184,
    sprmTFCantSplit = 185,
    sprmTTableHeader = 186,
    sprmTTableBorders = 187,
    sprmTDefTable10 = 188,
    sprmTDyaRowHeight = 189,
    sprmTDefTable = 190,
    sprmTDefTableShd = 191,
    sprmTTlp = 192,
    sprmTSetBrc = 193,
    sprmTInsert = 194,
    sprmTDelete = 195,
    sprmTDxaCol = 196,
    sprmTMerge = 197,
    sprmTSplit = 198,
    sprmTSetBrc10 = 199,
    sprmTSetShd = 200
} opcodes;

// The length of the SPRM parameter
U16 determineParameterLength(U8 sprm, const U8 *in)
{
    switch (sprm) {
    case SPRM::sprmNoop:
        return 0;
    case SPRM::sprmPIstd:
        return 2;
    case SPRM::sprmPIstdPermute:
        break; // Variable.
    case SPRM::sprmPIncLvl:
    case SPRM::sprmPJc:
    case SPRM::sprmPFSideBySide:
    case SPRM::sprmPFKeep:
    case SPRM::sprmPFKeepFollow:
    case SPRM::sprmPFPageBreakBefore:
    case SPRM::sprmPBrcl:
    case SPRM::sprmPBrcp:
        return 1;
    case SPRM::sprmPAnld:
        break; // Variable.
    case SPRM::sprmPNLvlAnm:
    case SPRM::sprmPFNoLineNumb:
        return 1;
    case SPRM::sprmPChgTabsPapx:
        break; // Variable.
    case SPRM::sprmPDxaRight:
        return 2;
    case SPRM::sprmPDxaLeft:
    case SPRM::sprmPNest:
    case SPRM::sprmPDxaLeft1:
        return 2;
    case SPRM::sprmPDyaLine:
        return 4;
    case SPRM::sprmPDyaBefore:
    case SPRM::sprmPDyaAfter:
        return 2;
    case SPRM::sprmPChgTabs:
        if (*in == 255) {
            U8 itbdDelMax = in[1];
            U8 itbdAddMax = in[1 + itbdDelMax * 4];
            return 1 + itbdDelMax * 4 + itbdAddMax * 3;
        } else
            return *in + 1;
    case SPRM::sprmPFInTable:
    case SPRM::sprmPFTtp:
        return 1;
    case SPRM::sprmPDxaAbs:
    case SPRM::sprmPDyaAbs:
    case SPRM::sprmPDxaWidth:
        return 2;
    case SPRM::sprmPPc:
        return 1;
    case SPRM::sprmPBrcTop10:
    case SPRM::sprmPBrcLeft10:
    case SPRM::sprmPBrcBottom10:
    case SPRM::sprmPBrcRight10:
    case SPRM::sprmPBrcBetween10:
    case SPRM::sprmPBrcBar10:
    case SPRM::sprmPFromText10:
        return 2;
    case SPRM::sprmPWr:
        return 1;
    case SPRM::sprmPBrcTop:
    case SPRM::sprmPBrcLeft:
    case SPRM::sprmPBrcBottom:
    case SPRM::sprmPBrcRight:
    case SPRM::sprmPBrcBetween:
    case SPRM::sprmPBrcBar:
        return 2;
    case SPRM::sprmPFNoAutoHyph:
        return 1;
    case SPRM::sprmPWHeightAbs:
    case SPRM::sprmPDcs:
    case SPRM::sprmPShd:
    case SPRM::sprmPDyaFromText:
    case SPRM::sprmPDxaFromText:
        return 2;
    case SPRM::sprmPFLocked:
    case SPRM::sprmPFWidowControl:
        return 1;
    case SPRM::sprmPRuler:
        break; // Variable.
    case SPRM::sprmCFStrikeRM:
    case SPRM::sprmCFRMark:
    case SPRM::sprmCFFldVanish:
        return 1;
    case SPRM::sprmCPicLocation:
        break; // Variable.
    case SPRM::sprmCIbstRMark:
        return 2;
    case SPRM::sprmCDttmRMark:
        return 4;
    case SPRM::sprmCFData:
        return 1;
    case SPRM::sprmCRMReason:
        return 2;
    case SPRM::sprmCChse:
        return 3;
    case SPRM::sprmCSymbol:
        break; // Variable.
    case SPRM::sprmCFOle2:
        return 1;
    case SPRM::sprmCIstd:
        return 2;
    case SPRM::sprmCIstdPermute:
    case SPRM::sprmCDefault:
        break; // Variable.
    case SPRM::sprmCPlain:
        return 0;
    case SPRM::sprmCFBold:
    case SPRM::sprmCFItalic:
    case SPRM::sprmCFStrike:
    case SPRM::sprmCFOutline:
    case SPRM::sprmCFShadow:
    case SPRM::sprmCFSmallCaps:
    case SPRM::sprmCFCaps:
    case SPRM::sprmCFVanish:
        return 1;
    case SPRM::sprmCFtc:
        return 2;
    case SPRM::sprmCKul:
        return 1;
    case SPRM::sprmCSizePos:
        return 3;
    case SPRM::sprmCDxaSpace:
    case SPRM::sprmCLid:
        return 2;
    case SPRM::sprmCIco:
    case SPRM::sprmCHps:
    case SPRM::sprmCHpsInc:
    case SPRM::sprmCHpsPos:
    case SPRM::sprmCHpsPosAdj:
        return 1;
    case SPRM::sprmCMajority:
        break; // Variable.
    case SPRM::sprmCIss:
        return 1;
    case SPRM::sprmCHpsNew50:
    case SPRM::sprmCHpsInc1:
        break; // Variable.
    case SPRM::sprmCHpsKern:
        return 2;
    case SPRM::sprmCMajority50:
        break; // Variable.
    case SPRM::sprmCHpsMul:
    case SPRM::sprmCCondHyhen:
        return 2;
    case SPRM::sprmCFSpec:
    case SPRM::sprmCFObj:
    case SPRM::sprmPicBrcl:
        return 1;
    case SPRM::sprmPicScale:
        break; // Variable.
    case SPRM::sprmPicBrcTop:
    case SPRM::sprmPicBrcLeft:
    case SPRM::sprmPicBrcBottom:
    case SPRM::sprmPicBrcRight:
        return 2;
    case SPRM::sprmSScnsPgn:
    case SPRM::sprmSiHeadingPgn:
        return 1;
    case SPRM::sprmSOlstAnm:
        break; // Variable.
    case SPRM::sprmSDxaColWidth:
    case SPRM::sprmSDxaColSpacing:
        return 3;
    case SPRM::sprmSFEvenlySpaced:
    case SPRM::sprmSFProtected:
        return 1;
    case SPRM::sprmSDmBinFirst:
    case SPRM::sprmSDmBinOther:
        return 2;
    case SPRM::sprmSBkc:
    case SPRM::sprmSFTitlePage:
        return 1;
    case SPRM::sprmSCcolumns:
    case SPRM::sprmSDxaColumns:
        return 2;
    case SPRM::sprmSFAutoPgn:
    case SPRM::sprmSNfcPgn:
        return 1;
    case SPRM::sprmSDyaPgn:
    case SPRM::sprmSDxaPgn:
        return 2;
    case SPRM::sprmSFPgnRestart:
    case SPRM::sprmSFEndnote:
    case SPRM::sprmSLnc:
    case SPRM::sprmSGprfIhdt:
        return 1;
    case SPRM::sprmSNLnnMod:
    case SPRM::sprmSDxaLnn:
    case SPRM::sprmSDyaHdrTop:
    case SPRM::sprmSDyaHdrBottom:
        return 2;
    case SPRM::sprmSLBetween:
    case SPRM::sprmSVjc:
        return 1;
    case SPRM::sprmSLnnMin:
    case SPRM::sprmSPgnStart:
        return 2;
    case SPRM::sprmSBOrientation:
    case SPRM::sprmSBCustomize:
        return 1;
    case SPRM::sprmSXaPage:
    case SPRM::sprmSYaPage:
    case SPRM::sprmSDxaLeft:
    case SPRM::sprmSDxaRight:
    case SPRM::sprmSDyaTop:
    case SPRM::sprmSDyaBottom:
    case SPRM::sprmSDzaGutter:
    case SPRM::sprmSDMPaperReq:
    case SPRM::sprmTJc:
    case SPRM::sprmTDxaLeft:
    case SPRM::sprmTDxaGapHalf:
        return 2;
    case SPRM::sprmTFCantSplit:
    case SPRM::sprmTTableHeader:
        return 1;
    case SPRM::sprmTTableBorders:
        return 12;
    case SPRM::sprmTDefTable10:
        return readU16(in) + 1;
    case SPRM::sprmTDyaRowHeight:
        return 2;
    case SPRM::sprmTDefTable:
        return readU16(in) + 1;
    case SPRM::sprmTDefTableShd:
        break; // Variable.
    case SPRM::sprmTTlp:
        return 4;
    case SPRM::sprmTSetBrc:
        return 5;
    case SPRM::sprmTInsert:
        return 4;
    case SPRM::sprmTDelete:
        return 2;
    case SPRM::sprmTDxaCol:
        return 4;
    case SPRM::sprmTMerge:
    case SPRM::sprmTSplit:
        return 2;
    case SPRM::sprmTSetBrc10:
        return 5;
    case SPRM::sprmTSetShd:
        return 4;
    }

    // Get length of variable size operand.
    return *in + 1;
}

} // namespace SPRM
} // namespace Word95
} // namespace wvWare
