/* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */

/* libmwaw
* Version: MPL 2.0 / LGPLv2+
*
* The contents of this file are subject to the Mozilla Public License Version
* 2.0 (the "License"); you may not use this file except in compliance with
* the License or as specified alternatively below. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* Major Contributor(s):
* Copyright (C) 2002 William Lachance (wrlach@gmail.com)
* Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
* Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
* Copyright (C) 2006, 2007 Andrew Ziem
* Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
*
*
* All Rights Reserved.
*
* For minor contributions see the git repository.
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
* in which case the provisions of the LGPLv2+ are applicable
* instead of those above.
*/

#include <cmath>
#include <iomanip>
#include <iostream>
#include <limits>
#include <sstream>

#include <librevenge/librevenge.h>

#include "MWAWFontConverter.hxx"
#include "MWAWGraphicListener.hxx"
#include "MWAWGraphicShape.hxx"
#include "MWAWGraphicStyle.hxx"
#include "MWAWHeader.hxx"
#include "MWAWParagraph.hxx"
#include "MWAWPictBitmap.hxx"
#include "MWAWPictData.hxx"
#include "MWAWPrinter.hxx"
#include "MWAWPosition.hxx"
#include "MWAWRSRCParser.hxx"
#include "MWAWSubDocument.hxx"

#include "ReadySetGoParser.hxx"

#include "ReadySetGoStyleManager.hxx"

/** Internal: the structures of a ReadySetGoStyleManager */
namespace ReadySetGoStyleManagerInternal
{

////////////////////////////////////////
//! Internal: the state of a ReadySetGoStyleManager
struct State {
  //! constructor
  State()
    : m_version(-1)
    , m_isDesignStudio(false)
    , m_colors()
    , m_patterns()
  {
  }

  //! init the color's list
  void initColors();
  //! init the patterns' list
  void initPatterns();

  //! the file version
  int m_version;
  //! a flag to know if we parse a Design Studio file
  bool m_isDesignStudio;
  //! the list of colors: v45
  std::vector<MWAWColor> m_colors;
  //! the list of patterns: v3
  std::vector<MWAWGraphicStyle::Pattern> m_patterns;
};

void State::initColors()
{
  if (!m_colors.empty()) return;
  if (m_version<5) {
    MWAW_DEBUG_MSG(("ReadSetGoStyleManagerInternal::initColors: unknown version\n"));
    return;
  }
  static uint32_t const values[797]= {
    0x000000, 0xffee00, 0xde4f16, 0xa1006a, 0xc5008e, 0x7d0089, 0x0c0087, 0x0075ad,
    0x00a36e, 0x080d02, 0x30007b, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
    0x000000, 0x000000, 0x000000, 0x000000, 0xe5dec5, 0xdcd9c7, 0xbaada4, 0xa6968d,
    0x827872, 0xaf9b8f, 0xa9988d, 0x857a74, 0x786e6b, 0x605857, 0x443c3e, 0xcfc9b5,
    0xcac6ba, 0xbeb5b2, 0xb0a6a6, 0x918e92, 0xaa9b98, 0x918d90, 0x75747e, 0x5b5a68,
    0x4d4d5c, 0x323543, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
    0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
    0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0xffffff, 0xdd0806, 0x008011,
    0x0000d4, 0x02abea, 0xf20884, 0xfcf305, 0xff37b9, 0x9c66fe, 0xff5f0d, 0x00cb00,
    0x4a1209, 0x848484, 0xf9e2a6, 0xfc4b44, 0xe0ad0d, 0xe06d9b, 0x79b4ff, 0x002eb2,
    0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
    0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
    0x000000, 0x000000, 0x000000, 0xffffff, 0xfff681, 0xfffb6b, 0xfff400, 0xc5b00a,
    0xa49300, 0x6a6000, 0xfff37a, 0xfff46b, 0xffef5e, 0xffed2f, 0xd9bd11, 0xa28b00,
    0x8e7e00, 0xffee7a, 0xffef6a, 0xffea57, 0xffd900, 0xc2a100, 0xa1850d, 0x73690f,
    0xffed7a, 0xffee76, 0xffe21c, 0xffd200, 0xc39800, 0x9a7f00, 0x847200, 0xffe97a,
    0xffea78, 0xffe01a, 0xffc700, 0xc89900, 0x846d00, 0x524d05, 0xffe072, 0xffd65f,
    0xffc51a, 0xffac00, 0xce8b00, 0x936c00, 0x5a4e09, 0xffd561, 0xffce4c, 0xf2b52b,
    0xcb8300, 0xc57e00, 0x906f00, 0x5b5101, 0xffd788, 0xffca74, 0xffa719, 0xff9800,
    0xcb7d00, 0x956500, 0x7f5800, 0xffe4a3, 0xffd483, 0xf59a4c, 0xed7f2e, 0xb2582a,
    0x7a4702, 0x4d3506, 0xffcb8b, 0xffb073, 0xff9351, 0xe67500, 0xc26200, 0x9b5405,
    0x43290d, 0xffc198, 0xff9e7c, 0xff855d, 0xff6d0d, 0xb85802, 0x723d07, 0x482904,
    0xffbdab, 0xff8e83, 0xff7061, 0xc64230, 0x8e3825, 0x582a23, 0xffc5ba, 0xff8e9e,
    0xec768e, 0xcc304f, 0xa3223a, 0x741019, 0x491010, 0xffb2b1, 0xff98a9, 0xdf5978,
    0xd62654, 0x9a2447, 0x611333, 0x44182e, 0xffc3bd, 0xebaab1, 0xca356a, 0xaa1743,
    0x8d0034, 0x711839, 0x591d1f, 0xffc0c3, 0xe97da2, 0xd55686, 0xaf0755, 0x7c1549,
    0x530b34, 0x431030, 0xffa8b9, 0xe76d9c, 0xdb3381, 0xb81063, 0xa1185b, 0x671544,
    0x440930, 0xffcedf, 0xda74b1, 0xbc1a88, 0x7c0056, 0x650049, 0x400031, 0xff7ac5,
    0xe85dac, 0xd33198, 0xb80081, 0x7d005e, 0x570046, 0x3c1036, 0xffbad4, 0xe46cb2,
    0xd0349e, 0xa6007b, 0x6c0059, 0x4a0040, 0xffa1d8, 0xef60c6, 0xc63ca5, 0xab0089,
    0x800071, 0x68005d, 0x3f003c, 0xffd0ed, 0xde95c5, 0xd067c2, 0x8d008a, 0x7c007c,
    0x66006e, 0x44004d, 0xf9d5ee, 0xe493ff, 0xab35be, 0x630074, 0x4e0058, 0x370047,
    0xe6b9d3, 0xd29bc6, 0x9145a5, 0x640a7f, 0x450f56, 0x3b174e, 0x351d4a, 0xdac4de,
    0xb18ad0, 0x6f2bb1, 0x48128a, 0x360570, 0x2f0a5e, 0x21054d, 0xc2a6cc, 0xab89c4,
    0x8c6fba, 0x3e1d88, 0x250765, 0x220c57, 0x1c0d45, 0xc2c9dc, 0xa8abdd, 0x7c89c4,
    0x06106a, 0x000e4f, 0x0a0c44, 0xc9d5f0, 0xa7b8df, 0x5f74e2, 0x253fb6, 0x001769,
    0x000067, 0x000e44, 0xc4d5e5, 0x94b0dc, 0x7592c7, 0x0000b4, 0x002a7f, 0x00286c,
    0x001c48, 0x8bb0c9, 0x6c97b8, 0x407fb3, 0x0f59a0, 0x004085, 0x002f5d, 0x00294d,
    0xcceae4, 0x7fcde1, 0x56a9c7, 0x006795, 0x004261, 0x002f4e, 0x9ed7d2, 0x72b7c1,
    0x2e8aa1, 0x007291, 0x006281, 0x00445f, 0x00293c, 0xdbffe4, 0xc7f5df, 0x72d6c1,
    0x009696, 0x00787d, 0x006b71, 0x004b55, 0xb7dfc2, 0x89d0b0, 0x6bb9a1, 0x178479,
    0x105f5e, 0x004f50, 0x16373f, 0xccf5c2, 0xc0f0be, 0x74e2a3, 0x17855c, 0x156e54,
    0x12584b, 0xa1e8b1, 0x82ce9d, 0x59aa80, 0x2a9167, 0x1b6d52, 0x245c4a, 0x11413d,
    0xc8eea5, 0xbcf4a2, 0x8dee88, 0x3bb253, 0x309540, 0x2a6f36, 0x2d4a1f, 0xc8f6a6,
    0xbcffa0, 0x92f58f, 0x2bcb4c, 0x318b40, 0x2a6739, 0x274730, 0xd6f094, 0xb7e36f,
    0x8fd44e, 0x5ea223, 0x4a7d22, 0x466c18, 0x3f5c12, 0xe5f491, 0xdaf173, 0xc0e752,
    0x89ca03, 0x76a600, 0x628000, 0x45520a, 0xf6ff74, 0xe8ff6c, 0xcce73d, 0xb0de00,
    0x98bd00, 0x7f9300, 0x515700, 0xf7f666, 0xe6f157, 0xd1e022, 0xc4d600, 0xacae00,
    0x989600, 0x6e6b00, 0xf9fa7e, 0xf4fa62, 0xedfa37, 0xecff0d, 0xbbbf00, 0x9f9900,
    0x747300, 0xfdf378, 0xf6f94f, 0xf1f220, 0xe9f200, 0xbfba00, 0xa19b00, 0x8e8603,
    0xd3c9af, 0xb2a390, 0x968d80, 0x827a6d, 0x5e5854, 0x33312e, 0xd6cab5, 0xb5a69a,
    0xaa9c97, 0x7c7371, 0x544a48, 0x433e44, 0x110f0a, 0xc8c0a6, 0xaca396, 0x89867d,
    0x656764, 0x4b4d4b, 0x393b3b, 0x131317, 0xc8c3bb, 0xbcb7b8, 0x8d8b92, 0x7f7d82,
    0x5d5b60, 0x3a3a48, 0x070b1c, 0xccc7bb, 0xb2acb0, 0x8f8f99, 0x787882, 0x515567,
    0x282e48, 0x0f1020, 0xccb0a6, 0xc3a49d, 0x9a7b7f, 0x78606a, 0x3f2d3d, 0x261a25,
    0x211b22, 0xd4d2c6, 0xbdbbb8, 0x8b8e91, 0x696a6d, 0x474850, 0x2e2e3b, 0x222422,
    0x3a3116, 0x4f463a, 0x594e2d, 0xa08f72, 0xad9d86, 0xc8ba95, 0xddd8ad, 0x544b25,
    0x7f7019, 0xa88f2f, 0xe2d360, 0xeae171, 0xf7ef83, 0xf7ee98, 0x594535, 0x6d4f2b,
    0x835a35, 0xc2a075, 0xd6ba8a, 0xdbc58e, 0xead9a3, 0x4d3522, 0x9f612e, 0xc26d21,
    0xe9a872, 0xe6b480, 0xf0cf99, 0xf3d59e, 0x3b292d, 0x5a3d3b, 0x683e3b, 0xa57f6f,
    0xb19286, 0xccab97, 0xd6c4af, 0x4f3020, 0x914120, 0xc83f31, 0xdb9279, 0xefab8d,
    0xebb298, 0xf5cfb0, 0x4e2b33, 0x602732, 0x702237, 0xc5707d, 0xe89b9e, 0xefb5b1,
    0xf4cab6, 0x3f291b, 0x593331, 0x723c38, 0xc7807e, 0xd59890, 0xe4b1a5, 0xf0cdb9,
    0x421f31, 0x532138, 0x602944, 0xbc6c83, 0xd28390, 0xe9a6a9, 0xecb8b8, 0x48264a,
    0x682f6f, 0x802e83, 0xc26aa9, 0xd38bb4, 0xeba5c2, 0xf7c7cf, 0x3b1d3e, 0x552961,
    0x62296f, 0xa6729a, 0xbc8da6, 0xd5aab9, 0xe7c7ce, 0x3c2056, 0x4e2077, 0x5b1c8b,
    0x9462a8, 0xba86c1, 0xd2a2cd, 0xe2c5e1, 0x211e3c, 0x2d234e, 0x3e376b, 0x8b8099,
    0xad9eb5, 0xb9afc2, 0xccc8d0, 0x18234c, 0x0f2d67, 0x0f337c, 0x657bab, 0x8c9bbc,
    0xa9b1c6, 0xc3cddc, 0x001b39, 0x093151, 0x1f4769, 0x597a96, 0x819cac, 0x9fabb3,
    0xc3cfcd, 0x192b00, 0x183e00, 0x214e27, 0x69866d, 0x95a690, 0xa5b19a, 0xb7c5aa,
    0x1d3027, 0x275046, 0x396c5d, 0x74a185, 0x92b499, 0xc4ddbe, 0xe1f6d7, 0x1b382d,
    0x164f3b, 0x2b6c55, 0x67a684, 0x93c79e, 0xb6d9b2, 0xd1e8c1, 0x394100, 0x4e6200,
    0x567700, 0xa6be64, 0xc8d885, 0xd5de87, 0xdde49a, 0x5a5600, 0x909100, 0xa5ae00,
    0xd0da5b, 0xdde365, 0xe7ec73, 0xe9ef8d, 0xffd170, 0xffcd64, 0xffb615, 0xff9c00,
    0xce8500, 0x7c5a00, 0x463400, 0xffcc8f, 0xffa963, 0xf58532, 0xf77800, 0xc26300,
    0x864e00, 0x573100, 0xffb68c, 0xffa57b, 0xff834f, 0xe66000, 0xc25600, 0x7d3b00,
    0x4d2700, 0xffa7a5, 0xff888f, 0xff6375, 0xde2c1a, 0xc62d37, 0x781915, 0x4f1818,
    0xca61ff, 0xbc39ff, 0x800ebe, 0x590089, 0x4c0074, 0x380058, 0x2f004e, 0xbf6bff,
    0xae3dff, 0x8a20db, 0x470080, 0x3d0070, 0x350063, 0x280052, 0xcf99ff, 0xa84eff,
    0x6c0fc0, 0x5100a0, 0x20005f, 0x1e124c, 0x9c79cc, 0x8e74cc, 0x6c22cf, 0x33008e,
    0x26006f, 0x1d0057, 0x170045, 0xbcd5da, 0x7cacd1, 0x569ac9, 0x2176c1, 0x13528a,
    0x00395d, 0x002540, 0x9ed7ca, 0x72b4b6, 0x0092a1, 0x0d768b, 0x00687c, 0x00475b,
    0x003548, 0xaee9c3, 0x7ee3b7, 0x50c39e, 0x00947c, 0x00786c, 0x00514f, 0x003238,
    0xacdfb7, 0x7cd0a6, 0x5eb996, 0x009176, 0x0a7160, 0x0c5b51, 0x0d3732, 0x86d6b0,
    0x70cda6, 0x29a889, 0x008a6e, 0x006e5c, 0x005749, 0x002e26, 0xa4e9a7, 0x7ce595,
    0x5cd481, 0x34a562, 0x308057, 0x245c44, 0x113823, 0xffff78, 0xfbfe4f, 0xf8fa20,
    0xe9ec00, 0xaba200, 0x858100, 0x595600, 0x4f420c, 0x776900, 0x8a7c3e, 0xbbab7e,
    0xbfb084, 0xcac49b, 0xd6d1a9, 0x452a00, 0x7e5943, 0xa17a62, 0xbe9675, 0xc9a98c,
    0xc9ac91, 0xd3ba9c, 0x4d2b32, 0x6a3e3e, 0x926e66, 0xae8474, 0xbc9580, 0xc8ac99,
    0xd1b79e, 0x432d3a, 0x714355, 0x92606d, 0xc6949a, 0xd5a4a7, 0xdbc2b9, 0xddccc3,
    0x3f184a, 0x632e6f, 0x8c5691, 0xba89ad, 0xc09ab3, 0xceb1c2, 0xd9c8cd, 0x2d1b3e,
    0x442952, 0x694870, 0x90728b, 0xac8d9f, 0xc2aab3, 0xd7c7c6, 0x1e004b, 0x3a2077,
    0x421c8b, 0x735cac, 0x9b84c1, 0xb7a4cd, 0xccc3e1, 0x061c50, 0x1b3365, 0x4d5f85,
    0x75809c, 0x9a9eb8, 0xb0afc5, 0xc3c8d4, 0x00253e, 0x1a475b, 0x517483, 0x899fa3,
    0xa2b4b4, 0xbccac2, 0xd1dcd0, 0x001b31, 0x18394c, 0x375363, 0x77878c, 0x94a0a0,
    0xadb4b0, 0xc8d0c7, 0x283840, 0x4c645c, 0x6a8377, 0x7b8f82, 0xa1ad9f, 0xafb9a8,
    0xc1ccb7, 0x172721, 0x3a504d, 0x576963, 0x909d91, 0xacb1a2, 0xc0ccb5, 0xd6dec8,
    0x343d29, 0x4a5735, 0x5d6c3d, 0x9ea175, 0xb1b07e, 0xc9cba2, 0xd8d9ae, 0x3f4511,
    0x5d6600, 0x7e8746, 0xb1b273, 0xc8cc91, 0xd5d9a2, 0xdddead, 0x494a2a, 0x71743d,
    0xa5a069, 0xc4c07d, 0xcac785, 0xd3d08f, 0xdad7a3
  };

  m_colors.resize(797);
  for (size_t i=0; i < 797; ++i)
    m_colors[i] = values[i];
}

void State::initPatterns()
{
  if (!m_patterns.empty()) return;
  if (m_version<3) {
    MWAW_DEBUG_MSG(("ReadSetGoParserInternal::initPatterns: unknown version\n"));
    return;
  }
  if (m_version==3) {
    static uint16_t const values[] = {
      0xffff, 0xffff, 0xffff, 0xffff,  0xddff, 0x77ff, 0xddff, 0x77ff,  0xdd77, 0xdd77, 0xdd77, 0xdd77,  0xaa55, 0xaa55, 0xaa55, 0xaa55,
      0x55ff, 0x55ff, 0x55ff, 0x55ff,  0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa,  0xeedd, 0xbb77, 0xeedd, 0xbb77,  0x8888, 0x8888, 0x8888, 0x8888,
      0xb130, 0x031b, 0xd8c0, 0x0c8d,  0x8010, 0x0220, 0x0108, 0x4004,  0xff88, 0x8888, 0xff88, 0x8888,  0xff80, 0x8080, 0xff08, 0x0808,
      0x0000, 0x0002, 0x0000, 0x0002,  0x8040, 0x2000, 0x0204, 0x0800,  0x8244, 0x3944, 0x8201, 0x0101,  0xf874, 0x2247, 0x8f17, 0x2271,
      0x55a0, 0x4040, 0x550a, 0x0404,  0x2050, 0x8888, 0x8888, 0x0502,  0xbf00, 0xbfbf, 0xb0b0, 0xb0b0,  0x0000, 0x0000, 0x0000, 0x0000,
      0x8000, 0x0800, 0x8000, 0x0800,  0x8800, 0x2200, 0x8800, 0x2200,  0x8822, 0x8822, 0x8822, 0x8822,  0xaa00, 0xaa00, 0xaa00, 0xaa00,
      0x00ff, 0x00ff, 0x00ff, 0x00ff,  0x1122, 0x4488, 0x1122, 0x4488,  0x8040, 0x2000, 0x0204, 0x0800,  0x0102, 0x0408, 0x1020, 0x4080,
      0xaa00, 0x8000, 0x8800, 0x8000,  0xff80, 0x8080, 0x8080, 0x8080,  0x0814, 0x2241, 0x8001, 0x0204,  0x8814, 0x2241, 0x8800, 0xaa00,
      0x40a0, 0x0000, 0x040a, 0x0000,  0x0384, 0x4830, 0x0c02, 0x0101,  0x8080, 0x413e, 0x0808, 0x14e3,  0x1020, 0x54aa, 0xff02, 0x0408,
      0x7789, 0x8f8f, 0x7798, 0xf8f8,  0x0008, 0x142a, 0x552a, 0x1408,  0x0000, 0x0000, 0x0000, 0x0000,
    };
    size_t N=MWAW_N_ELEMENTS(values)/4;
    m_patterns.resize(N);
    uint16_t const *ptr=values;
    for (size_t i=0; i<N; ++i) {
      auto &pat=m_patterns[i];
      pat.m_dim=MWAWVec2i(8,8);
      pat.m_data.resize(8);
      for (size_t j=0; j<8; j+=2) {
        pat.m_data[j]=uint8_t(~(*ptr>>8));
        pat.m_data[j+1]=uint8_t(~(*(ptr++)&0xff));
      }
    }
    return;
  }
  if (m_version<6 || (m_isDesignStudio && m_version==6)) {
    static uint16_t const values[] = {
      0xffff, 0xffff, 0xffff, 0xffff, 0x7f7f, 0x7f7f, 0x7f7f, 0x7f7f, 0xff, 0xffff, 0xffff, 0xffff, 0xefdf, 0xbf7f, 0xfefd, 0xfbf7,
      0xbfff, 0xffff, 0xfbff, 0xffff, 0x3f3f, 0x3f3f, 0x3f3f, 0x3f3f, 0x0, 0xffff, 0xffff, 0xffff, 0xe7cf, 0x9f3f, 0x7efc, 0xf9f3,
      0xff77, 0xffff, 0xffdd, 0xffff, 0x1f1f, 0x1f1f, 0x1f1f, 0x1f1f, 0x0, 0xff, 0xffff, 0xffff, 0xe3c7, 0x8f1f, 0x3e7c, 0xf8f1,
      0xddff, 0x77ff, 0xddff, 0x77ff, 0xf0f, 0xf0f, 0xf0f, 0xf0f, 0x0, 0x0, 0xffff, 0xffff, 0xe1c3, 0x870f, 0x1e3c, 0x78f0,
      0xdd77, 0xdd77, 0xdd77, 0xdd77, 0x707, 0x707, 0x707, 0x707, 0x0, 0x0, 0xff, 0xffff, 0xc183, 0x70e, 0x1c38, 0x70e0,
      0xaa55, 0xaa55, 0xaa55, 0xaa55, 0x303, 0x303, 0x303, 0x303, 0x0, 0x0, 0x0, 0xffff, 0x306, 0xc18, 0x3060, 0xc081,
      0x8822, 0x8822, 0x8822, 0x8822, 0x8080, 0x8080, 0x8080, 0x8080, 0x0, 0x0, 0x0, 0xff, 0x102, 0x408, 0x1020, 0x4080,
      0x8800, 0x2200, 0x8800, 0x2200, 0x8888, 0x8888, 0x8888, 0x8888, 0xff, 0x0, 0xff, 0x0, 0x1122, 0x4488, 0x1122, 0x4488,
      0x8000, 0x800, 0x8000, 0x800, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x0, 0xffff, 0x0, 0xffff, 0x3366, 0xcc99, 0x3366, 0xcc99,
      0x0, 0x2000, 0x0, 0x200, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, 0xff, 0xffff, 0xff, 0xffff, 0x77ee, 0xddbb, 0x77ee, 0xddbb,
      0x0, 0x0, 0x0, 0x0, 0x40a0, 0x0, 0x40a, 0x0, 0xff80, 0x8080, 0xff08, 0x808, 0xff77, 0x3311, 0xff77, 0x3311, 0xb130,
      0x31b, 0xd8c0, 0xc8d, 0x8040, 0x2000, 0x204, 0x800, 0x8010, 0x220, 0x108, 0x4004, 0x4, 0xc3f, 0x1c2c, 0x4400,
      0x0, 0x0, 0x0, 0x0, /* none*/ 0x7789, 0x8f8f, 0x7798, 0xf8f8, 0x8, 0x142a, 0x552a, 0x1408, 0xfffb, 0xf3c0, 0xe3d3, 0xbbff,
    };
    size_t N=MWAW_N_ELEMENTS(values)/4;
    m_patterns.resize(N);
    uint16_t const *ptr=values;
    for (size_t i=0; i<N; ++i) {
      auto &pat=m_patterns[i];
      pat.m_dim=MWAWVec2i(8,8);
      pat.m_data.resize(8);
      for (size_t j=0; j<8; j+=2) {
        pat.m_data[j]=uint8_t(~(*ptr>>8));
        pat.m_data[j+1]=uint8_t(~(*(ptr++)&0xff));
      }
    }
    return;
  }

  static uint16_t const values[] = {
    0xffff, 0xffff, 0xffff, 0xffff, 0xff, 0xffff, 0xffff, 0xffff, 0xefdf, 0xbf7f, 0xfefd, 0xfbf7, 0x0, 0x0, 0x0, 0x0, /* none */
    0x0, 0xffff, 0xffff, 0xffff, 0xe7cf, 0x9f3f, 0x7efc, 0xf9f3, 0x1f1f, 0x1f1f, 0x1f1f, 0x1f1f, 0x0, 0xff, 0xffff, 0xffff,
    0xe3c7, 0x8f1f, 0x3e7c, 0xf8f1, 0xf0f, 0xf0f, 0xf0f, 0xf0f, 0x0, 0x0, 0xffff, 0xffff, 0xe1c3, 0x870f, 0x1e3c, 0x78f0,
    0x707, 0x707, 0x707, 0x707, 0x0, 0x0, 0xff, 0xffff, 0xc183, 0x70e, 0x1c38, 0x70e0, 0x303, 0x303, 0x303, 0x303,
    0x0, 0x0, 0x0, 0xffff, 0x306, 0xc18, 0x3060, 0xc081, 0x8080, 0x8080, 0x8080, 0x8080, 0x0, 0x0, 0x0, 0xff,
    0x102, 0x408, 0x1020, 0x4080, 0x8888, 0x8888, 0x8888, 0x8888, 0xff, 0x0, 0xff, 0x0, 0x1122, 0x4488, 0x1122, 0x4488,
    0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x0, 0xffff, 0x0, 0xffff, 0x3366, 0xcc99, 0x3366, 0xcc99, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa,
    0xff, 0xffff, 0xff, 0xffff, 0x77ee, 0xddbb, 0x77ee, 0xddbb, 0x40a0, 0x0, 0x40a, 0x0, 0xff80, 0x8080, 0xff08, 0x808,
    0xff77, 0x3311, 0xff77, 0x3311, 0x8040, 0x2000, 0x204, 0x800, 0x8010, 0x220, 0x108, 0x4004, 0x4, 0xc3f, 0x1c2c, 0x4400,
    0x7789, 0x8f8f, 0x7798, 0xf8f8, 0x8, 0x142a, 0x552a, 0x1408, 0xfffb, 0xf3c0, 0xe3d3, 0xbbff, 0xb130, 0x31b, 0xd8c0, 0xc8d,
    0x3f3f, 0x3f3f, 0x3f3f, 0x3f3f, 0x7f7f, 0x7f7f, 0x7f7f, 0x7f7f
  };
  size_t N=MWAW_N_ELEMENTS(values)/4;
  m_patterns.resize(N);
  uint16_t const *ptr=values;
  for (size_t i=0; i<N; ++i) {
    auto &pat=m_patterns[i];
    pat.m_dim=MWAWVec2i(8,8);
    pat.m_data.resize(8);
    for (size_t j=0; j<8; j+=2) {
      pat.m_data[j]=uint8_t(~(*ptr>>8));
      pat.m_data[j+1]=uint8_t(~(*(ptr++)&0xff));
    }
  }
}

}

////////////////////////////////////////////////////////////
// constructor/destructor, ...
////////////////////////////////////////////////////////////
ReadySetGoStyleManager::ReadySetGoStyleManager(ReadySetGoParser &parser)
  : m_parser(parser)
  , m_parserState(parser.getParserState())
  , m_state(new ReadySetGoStyleManagerInternal::State)
{
}

ReadySetGoStyleManager::~ReadySetGoStyleManager()
{
}

int ReadySetGoStyleManager::version() const
{
  if (m_state->m_version==-1) {
    int const vers=m_parser.version();
    m_state->m_version=vers;
    m_state->m_isDesignStudio=m_parser.isDesignStudioFile();
    m_state->m_colors.clear();
    if (vers>=5)
      m_state->initColors();
  }
  return m_state->m_version;
}

bool ReadySetGoStyleManager::getColor(int colorId, MWAWColor &color) const
{
  if (colorId>0 && size_t(colorId)<m_state->m_colors.size()) {
    color=m_state->m_colors[size_t(colorId)];
    return true;
  }
  MWAW_DEBUG_MSG(("ReadySetGoParser::getColor: unknown color id=%d\n", colorId));
  return false;
}

bool ReadySetGoStyleManager::getPattern(int patternId, MWAWGraphicStyle::Pattern &pattern) const
{
  version();
  if (m_state->m_patterns.empty())
    m_state->initPatterns();
  if (patternId < 0 || size_t(patternId) >= m_state->m_patterns.size()) {
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::getPattern: can not find pattern %d\n", patternId));
    return false;
  }
  pattern=m_state->m_patterns[size_t(patternId)];
  return true;
}

////////////////////////////////////////////////////////////
//
// Intermediate level
//
////////////////////////////////////////////////////////////
bool ReadySetGoStyleManager::readColors()
{
  int const vers=version();
  if (vers<5) {
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readColors: unexpected version\n"));
    return false;
  }
  MWAWInputStreamPtr input = m_parser.getInput();
  if (!input)
    return false;
  long pos=input->tell();
  if (!input->checkPosition(pos+120)) {
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readColors: can not find the data\n"));
    return false;
  }
  libmwaw::DebugStream f;
  libmwaw::DebugFile &ascFile=m_parser.ascii();
  f << "Entries(Colors):";
  if (m_state->m_colors.size()<60+20) {
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readColors: can not use the data\n"));
    f << "###";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    input->seek(pos+120, librevenge::RVNG_SEEK_SET);
    return true;
  }
  f << "colors=[";
  for (size_t i=0; i<20; ++i) {
    uint8_t colors[3];
    for (auto &c : colors) c=uint8_t(input->readULong(2)>>8);
    m_state->m_colors[60+i]=MWAWColor(colors[0],colors[1],colors[2]);
    f << m_state->m_colors[60+i] << ",";
  }
  f << "],";
  ascFile.addPos(pos);
  ascFile.addNote(f.str().c_str());
  return true;
}

bool ReadySetGoStyleManager::readColorNames()
{
  int const vers=version();
  if (vers<5) {
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readColorNames: unexpected version\n"));
    return false;
  }
  MWAWInputStreamPtr input = m_parser.getInput();
  if (!input)
    return false;
  long pos=input->tell();
  if (!input->checkPosition(pos+4)) {
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readColorNames: can not find the data\n"));
    return false;
  }
  libmwaw::DebugStream f;
  libmwaw::DebugFile &ascFile=m_parser.ascii();
  f << "Entries(ColorNames):";
  long len=long(input->readLong(4));
  if (len==0) {
    ascFile.addPos(pos);
    ascFile.addNote("_");
    return true;
  }
  long endPos=pos+4+len;
  if (len<20 || endPos<pos+4 || !input->checkPosition(endPos)) {
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readColorNames: can not find the data\n"));
    f << "###";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    return false;
  }

  f << "names=[";
  for (int i=0; i<20; ++i) {
    int cLen=int(input->readULong(1));
    if (input->tell()+cLen>endPos) {
      MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readColorNames: can not read a name\n"));
      f << "###";
      break;
    }
    std::string name;
    for (int c=0; c<cLen; ++c) {
      char ch=char(input->readLong(1));
      if (ch)
        name+=ch;
    }
    f << name << ",";
  }
  f << "],";
  ascFile.addPos(pos);
  ascFile.addNote(f.str().c_str());
  if (input->tell()!=endPos)
    ascFile.addDelimiter(input->tell(),'|');
  return true;
}

bool ReadySetGoStyleManager::readFontsBlock()
{
  MWAWInputStreamPtr input = m_parser.getInput();
  if (!input)
    return false;
  int const vers=version();
  long pos=input->tell();
  libmwaw::DebugStream f;
  libmwaw::DebugFile &ascFile = m_parser.ascii();
  f << "Entries(FontBlock):";
  if (vers<5) {
    f << "###";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readFontsBlock: unexpected version\n"));
    return false;
  }
  long len=long(input->readLong(4));
  long endPos=pos+4+len;
  if (len<4 || endPos<pos+8 || !input->checkPosition(endPos)) {
    f << "###";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readFontsBlock: the zone's length seems bad\n"));
    return false;
  }

  int N=int(input->readULong(2));
  int const dataSize=vers==5 ? 1110 : 1106;
  f << "N=" << N << ",";
  if (N<0 || (len-(m_parser.isDesignStudioFile() ? 2 : 4))/dataSize<N) {
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readFontsBlock: the n values seems bad\n"));
    f << "###";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    N=0;
  }
  f << "unk=" << input->readLong(2) << ",";
  ascFile.addPos(pos);
  ascFile.addNote(f.str().c_str());
  for (int i=0; i<N; ++i) {
    pos=input->tell();
    if (pos+dataSize > endPos)
      break;
    f.str("");
    f << "FontBlock-A" << i << ":";
    int cLen=int(input->readULong(1));
    if (cLen>63) {
      MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readFontsBlock: the name seems too long\n"));
      f << "###";
      cLen=0;
    }
    std::string name;
    for (int c=0; c<cLen; ++c) {
      char ch=char(input->readLong(1));
      if (ch==0)
        break;
      name+=ch;
    }
    f << name << ",";
    ascFile.addDelimiter(pos+64,'|');
    input->seek(pos+dataSize, librevenge::RVNG_SEEK_SET);
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
  }
  input->seek(endPos, librevenge::RVNG_SEEK_SET);

  if (vers>5) return true;
  for (int i=0; i<N; ++i) {
    pos=input->tell();
    len=long(input->readLong(4));
    f.str("");
    f << "FontBlock-B" << i << ":";
    if ((long)((unsigned long)pos+4+(unsigned long)len)<pos+4 || !input->checkPosition(pos+4+len)) {
      MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readFontsBlock: can not find a data block\n"));
      f << "###";
      ascFile.addPos(pos);
      ascFile.addNote(f.str().c_str());
      return false;
    }
    if (len==0) {
      ascFile.addPos(pos);
      ascFile.addNote("_");
      continue;
    }
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    input->seek(pos+4+len, librevenge::RVNG_SEEK_SET);
  }

  return true;
}

bool ReadySetGoStyleManager::readFontsBlock2()
{
  MWAWInputStreamPtr input = m_parser.getInput();
  if (!input)
    return false;
  int const vers=version();
  long pos=input->tell();
  libmwaw::DebugFile &ascFile = m_parser.ascii();
  libmwaw::DebugStream f;
  f << "Entries(FontBlck2):";
  if (vers<6) {
    f << "###";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readFontsBlock2: unexpected version\n"));
    return false;
  }
  long len=long(input->readLong(4));
  long endPos=pos+4+len;
  if (endPos<pos+4 || !input->checkPosition(endPos)) {
    f << "###";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readFontsBlock2: the zone's length seems bad\n"));
    return false;
  }
  ascFile.addPos(pos);
  ascFile.addNote(f.str().c_str());

  int N=int(len/260);
  for (int n=0; n<N; ++n) {
    pos=input->tell();
    f.str("");
    f << "FontBlck2-" << n << ":";
    f << "id=" << input->readLong(2) << ",";
    int val=int(input->readLong(2));
    if (val) f << "f0=" << val << ",";
    int cLen=int(input->readULong(1));
    if (cLen>63) {
      MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readFontsBlock2: the name seems too long\n"));
      f << "###";
      cLen=0;
    }
    std::string name;
    for (int c=0; c<cLen; ++c) {
      char ch=char(input->readLong(1));
      if (ch==0)
        break;
      name+=ch;
    }
    f << name << ",";
    ascFile.addDelimiter(pos+4+64,'|');
    input->seek(pos+260, librevenge::RVNG_SEEK_SET);
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
  }
  input->seek(endPos, librevenge::RVNG_SEEK_SET);
  return true;
}

bool ReadySetGoStyleManager::readFontsName()
{
  MWAWInputStreamPtr input = m_parser.getInput();
  if (!input)
    return false;
  int const vers=version();
  long pos=input->tell();
  libmwaw::DebugFile &ascFile = m_parser.ascii();
  libmwaw::DebugStream f;
  f << "Entries(FontName):";
  if (vers<6) {
    f << "###";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readFontsName: unexpected version\n"));
    return false;
  }
  long len=long(input->readLong(4));
  long endPos=pos+4+len;
  if (len<4 || endPos<pos+8 || !input->checkPosition(endPos)) {
    f << "###";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readFontsName: the zone's length seems bad\n"));
    return false;
  }
  ascFile.addPos(pos);
  ascFile.addNote(f.str().c_str());

  int N=int(len/68);
  for (int i=0; i<N; ++i) {
    pos=input->tell();
    f.str("");
    f << "FontName-" << i << ":";
    int cLen=int(input->readULong(1));
    if (cLen>63) {
      MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readFontsName: can not read a name\n"));
      f << "###";
      ascFile.addPos(pos);
      ascFile.addNote(f.str().c_str());
      break;
    }
    std::string name;
    for (int c=0; c<cLen; ++c) {
      char ch=char(input->readLong(1));
      if (ch)
        name+=ch;
    }
    f << name << ",";
    input->seek(pos+64, librevenge::RVNG_SEEK_SET);
    int fId=int(input->readLong(2));
    f << "id=" << fId << ",";
    if (!name.empty())
      m_parser.getFontConverter()->setCorrespondance(fId, name);
    int val=int(input->readLong(2));
    if (val)
      f << "f0=" << val << ",";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
  }
  return true;
}

bool ReadySetGoStyleManager::readStyles(int numStyles)
{
  MWAWInputStreamPtr input = m_parser.getInput();
  if (!input)
    return false;
  int const vers=version();
  long pos=input->tell();
  libmwaw::DebugFile &ascFile = m_parser.ascii();
  libmwaw::DebugStream f;
  f << "Entries(Style):";
  if (vers<4) {
    f << "###";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readStyles: unexpected version\n"));
    return false;
  }
  long len=long(input->readLong(4));
  long endPos=pos+4+len;
  if (endPos<pos+4 || !input->checkPosition(endPos)) {
    f << "###";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readStyles: the zone's length seems bad\n"));
    return false;
  }
  int const dataSize=vers==4 ? 74 : vers==5 ? 82 : vers==6 ? (m_parser.isDesignStudioFile() ? 90 : 92) : 98;
  if (numStyles<0 || numStyles*dataSize>len) {
    f << "###";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readStyles: the zone's length seems too short\n"));
    return false;
  }
  if (len==0) {
    ascFile.addPos(pos);
    ascFile.addNote("_");
  }
  ascFile.addPos(pos);
  ascFile.addNote(f.str().c_str());

  int N=int(len/dataSize), numTabZones=0;
  for (int i=0; i<N; ++i) {
    pos=input->tell();
    f.str("");
    f << "Style-" << i << ":";
    int cLen=int(input->readULong(1));
    if (cLen>39) {
      MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readStyles: can not determine the name length\n"));
      f << "##name[len]=" << cLen << ",";
      cLen=0;
    }
    std::string name;
    for (auto j=0; j<cLen; ++j) {
      char c=char(input->readLong(1));
      if (!c)
        break;
      name+=c;
    }
    f << name << ",";
    input->seek(pos+40, librevenge::RVNG_SEEK_SET);
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());

    int cPos;
    MWAWFont font;
    MWAWParagraph para;
    readStyle(font, para, &cPos);

    pos=input->tell();
    input->seek(pos, librevenge::RVNG_SEEK_SET);
    f.str("");
    f << "Style-id" << ":";
    if (vers>6)
      input->seek(6, librevenge::RVNG_SEEK_CUR);
    long tabId=long(input->readULong(4));
    if (tabId) {
      ++numTabZones;
      f << "tab[id]=" << std::hex << tabId << std::dec << ",";
    }
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
  }
  if (input->tell()!=endPos) {
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readStyles: find extra data\n"));
    ascFile.addPos(input->tell());
    ascFile.addNote("Style:extra#");
  }
  input->seek(endPos, librevenge::RVNG_SEEK_SET);

  for (int i=0; i<numTabZones; ++i) {
    int cPos=0;
    std::vector<MWAWTabStop> tabs;
    if (!readTabulations(tabs, -1, &cPos))
      return false;
  }
  return true;
}

bool ReadySetGoStyleManager::readStyle(MWAWFont &font, MWAWParagraph &para, int *cPos)
{
  font=MWAWFont();
  para=MWAWParagraph();
  MWAWInputStreamPtr input = m_parser.getInput();
  if (!input)
    return false;
  int const vers=version();
  long pos=input->tell();
  libmwaw::DebugStream f;
  f << "Style:";
  libmwaw::DebugFile &ascFile = m_parser.ascii();
  if (vers<3) {
    f << "###";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readStyle: unexpected version\n"));
    return false;
  }

  long endPos=pos+(vers==3 ? 22 : vers==4 ? 26 : vers== 5 ? 34 : m_parser.isDesignStudioFile() ? 42 : 44)+(cPos ? 4 : 0);
  if (!input->checkPosition(endPos)) {
    f << "###";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readStyle: the zone is too short\n"));
    return false;
  }
  if (cPos) {
    *cPos=int(input->readLong(4));
    f << "pos[char]=" << *cPos << ",";
  }

  font.setId(int(input->readULong(2)));
  para.m_marginsUnit=librevenge::RVNG_INCH;
  for (int i=0; i<3; ++i)
    para.m_margins[i]=float(input->readLong(4))/65536;
  para.m_margins[0]=*para.m_margins[0]-*para.m_margins[1];
  if (vers<=4)
    font.setSize(float(input->readULong(1)));
  else
    font.setSize(float(input->readULong(2))/100);
  int val=int(input->readULong(1));
  uint32_t flags=0;
  if (val&0x1) flags |= MWAWFont::boldBit;
  if (val&0x2) flags |= MWAWFont::italicBit;
  if (val&0x4) font.setUnderlineStyle(MWAWFont::Line::Simple);
  if (val&0x8) flags |= MWAWFont::embossBit;
  if (val&0x10) flags |= MWAWFont::shadowBit;
  if (val&0x80) font.setStrikeOutStyle(MWAWFont::Line::Simple); // only v4
  if (val&0x60) f << "fl=#" << std::hex << (val&0x60) << std::dec << ",";
  font.setFlags(flags);
  if (vers<=4) {
    val=int(input->readULong(1));
    if (val<100)
      para.setInterline(val, librevenge::RVNG_POINT, MWAWParagraph::AtLeast);
    else if (val && val!=100) {
      MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readStyle: unexpected interline\n"));
      f << "###interline=" << val << ",";
    }
    val=int(input->readULong(1));
    if (val && val<40)
      para.m_spacings[1]=double(val)/72;
    else {
      MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readStyle: unexpected paragraph spacing\n"));
      f << "###para[spacing]=" << val << ",";
    }
  }
  else {
    input->seek(1, librevenge::RVNG_SEEK_CUR);
    val=int(input->readULong(2));
    if (val<100*100)
      para.setInterline(float(val)/100, librevenge::RVNG_POINT, MWAWParagraph::AtLeast);
    else if (val && val!=100*100) {
      MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readStyle: unexpected interline\n"));
      f << "###interline=" << float(val)/100 << ",";
    }
    val=int(input->readULong(2));
    if (val && val<40*100)
      para.m_spacings[1]=double(val)/72/100;
    else if (val && val!=65535) { // -1: means no set
      MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readStyle: unexpected paragraph spacing\n"));
      f << "###para[spacing]=" << val << ",";
    }
  }
  val=int(input->readULong(1));
  switch (val & 7) {
  case 1:
    para.m_justify = MWAWParagraph::JustificationRight;
    break;
  case 2:
    para.m_justify = MWAWParagraph::JustificationCenter;
    break;
  case 3:
    para.m_justify = MWAWParagraph::JustificationFull;
    break;
  case 4:
    para.m_justify = MWAWParagraph::JustificationFullAllLines;
    break;
  case 0: // left
    break;
  default:
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readStyle: unexpected justification\n"));
    f << "###para[justify]=" << (val&7) << ",";
    break;
  }
  if (val&0xf8) f << "fl1=" << std::hex << (val&0xf8) << std::dec << ",";
  val=int(input->readLong(1));
  if (val) f << "f0=" << val << ",";
  if (vers<=4) {
    val=int(input->readLong(1));
    if (val) font.setDeltaLetterSpacing(float(val), librevenge::RVNG_POINT);
    val=int(input->readLong(1));
    if (val) font.set(MWAWFont::Script(-float(val), librevenge::RVNG_POINT));
  }
  else {
    val=int(input->readLong(2));
    if (val) font.set(MWAWFont::Script(-float(val)/100, librevenge::RVNG_POINT));
    val=int(input->readLong(2));
    if (val) font.setDeltaLetterSpacing(float(val)/100, librevenge::RVNG_POINT);
  }
  if (vers>=4) {
    val=int(input->readULong(1));
    if (val!=100)
      f << "word[spacing]=" << val << "%,";
    val=int(input->readULong(1));
    if (val!=100) {
      if (vers<=5) // checkme, there is no menu to set the horizontal scaling in 4.5
        f << "f1=" << val << "%,";
      else {
        if (val<=500)
          font.setWidthStreching(float(val)/100);
        else {
          MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readStyle: find unexpected streching\n"));
          f << "hor[scale]=###" << val << ",";
        }
      }
    }
  }
  if (vers>=5) {
    int col=int(input->readULong(2));
    int tint=100;
    if (vers>=6) {
      val=int(input->readULong(2));
      if (val!=1000)
        f << "f1=" << val << ",";
      tint=int(input->readULong(1));
      if (tint!=100)
        f << "tint=" << tint << "%,";
    }
    if (col>=0 && size_t(col)<m_state->m_colors.size()) {
      if (tint>=0 && tint<=100)
        font.setColor(MWAWColor::barycenter(1-float(tint)/100, MWAWColor::white(), float(tint)/100, m_state->m_colors[size_t(col)]));
      else
        font.setColor(m_state->m_colors[size_t(col)]);
    }
    else {
      MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readStyle: find unexpected paragraph color\n"));
      f << "color=###" << col << ",";
    }
    // v6: last value is trapping *1000 but unsure is trapping
  }
  f << font.getDebugString(m_parser.getFontConverter())  << ",";
  f << para << ",";

  ascFile.addPos(pos);
  ascFile.addNote(f.str().c_str());
  if (input->tell()!=endPos)
    ascFile.addDelimiter(input->tell(),'|');
  input->seek(endPos, librevenge::RVNG_SEEK_SET);

  return true;
}

bool ReadySetGoStyleManager::readTabulationsV1(std::vector<MWAWTabStop> &tabulations, std::string &extra)
{
  tabulations.clear();
  MWAWInputStreamPtr input = m_parser.getInput();
  if (!input)
    return false;
  int const vers=version();
  long pos=input->tell();
  if (vers>=3) {
    extra="###";
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readTabulationsV1: unexpected version\n"));
    return false;
  }
  long endPos=pos+(vers<=1 ? 40 : 32);
  if (!input->checkPosition(endPos)) {
    extra="###";
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readTabulationsV1: bad length\n"));
    return false;
  }
  libmwaw::DebugStream f;

  MWAWTabStop tabs[5];
  if (vers==1) {
    for (int i=0; i<5; ++i) {
      tabs[i].m_position=int(input->readLong(2));
      tabs[i].m_position+=float(input->readLong(2))/10000;
      if (tabs[i].m_position>0)
        f << "tab" << i << "[pos]=" << tabs[i].m_position << ",";
    }
  }
  else {
    for (int i=0; i<5; ++i) tabs[i].m_position=int(input->readLong(2));
    for (int i=0; i<5; ++i) {
      tabs[i].m_position+=float(input->readLong(2))/10000;
      if (tabs[i].m_position>0)
        f << "tab" << i << "[pos]=" << tabs[i].m_position << ",";
    }
  }
  bool tabOn[5];
  for (int i=0; i<5; ++i) {
    int val=int(input->readLong(vers<=1 ? 2 : 1));
    tabOn[i]=val==1;
    if (val==(vers==1 ? -1 : 0)) // off
      continue;
    if (val==1)
      f << "tab" << i << "=on,";
    else
      f << "tab" << i << "[on]=" << val << ",";
  }
  if (vers==2)
    input->seek(1, librevenge::RVNG_SEEK_CUR);
  for (int i=0; i<5; ++i) {
    int val=int(input->readLong(vers<=1 ? 2 : 1));
    if (val==1) // left
      continue;
    if (val==(vers==1 ? -1 : 0)) {
      tabs[i].m_alignment=MWAWTabStop::DECIMAL;
      f << "tab" << i << "=decimal,";
    }
    else
      f << "tab" << i << "[type]=" << val << ",";
  }
  if (vers==2)
    input->seek(1, librevenge::RVNG_SEEK_CUR);

  for (int i=0; i<5; ++i) {
    if (tabOn[i])
      tabulations.push_back(tabs[i]);
  }

  extra=f.str();
  return true;
}

bool ReadySetGoStyleManager::readTabulations(std::vector<MWAWTabStop> &tabs, long len, int *cPos)
{
  tabs.clear();
  MWAWInputStreamPtr input = m_parser.getInput();
  if (!input)
    return false;
  int const vers=version();
  long pos=input->tell();
  long endPos=pos+len;
  if (len<=0) {
    len=long(input->readLong(4));
    endPos=pos+4+len;
  }
  libmwaw::DebugStream f;
  libmwaw::DebugFile &ascFile=m_parser.ascii();
  f << "Tabs[list]:";
  if (vers<3) {
    f << "###";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readTabulations: unexpected version\n"));
    return false;
  }
  if (len<2+(len<=0 ? 4 : 0)+(cPos ? 4 : 0) || !input->checkPosition(endPos)) {
    f << "###";
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readTabulations: bad length\n"));
    return false;
  }
  if (cPos) {
    *cPos=int(input->readLong(4));
    f << "pos[char]=" << *cPos << ",";
  }
  int N=int(input->readLong(2));
  f << "N=" << N << ",";
  int const dataSize=vers<=3 ? 10 : 14;
  if (N<0 || 2+(cPos ? 4 : 0) + dataSize*N > len) {
    MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readTabulations: can not read the number of tabs\n"));
    f << "###";
    N=0;
  }
  ascFile.addPos(pos);
  ascFile.addNote(f.str().c_str());

  for (int i=0; i<N; ++i) {
    pos=input->tell();
    f.str("");
    f << "Tabs" << i << ":";
    MWAWTabStop tab;
    tab.m_position=float(input->readLong(4))/65536;
    f << "pos=" << tab.m_position << ",";
    int val=int(input->readLong(4));
    if (val)
      f << "measure=" << float(val)/65536 << ",";
    val=int(input->readLong(1));
    switch (val) {
    case 0: // left
      f << "left,";
      break;
    case 1:
      tab.m_alignment=MWAWTabStop::CENTER;
      f << "center,";
      break;
    case 2:
      tab.m_alignment=MWAWTabStop::RIGHT;
      f << "right,";
      break;
    case 3:
      tab.m_alignment=MWAWTabStop::DECIMAL;
      f << "decimal,";
      break;
    default:
      MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readTabulations: unknown tab's alignment\n"));
      f << "###align=" << val << ",";
    }
    val=int(input->readLong(1));
    if (val) {
      f << "on,";
      if (val!=1) {
        f << "leader=" << char(val) << ",";
        int unicode=m_parser.getFontConverter()->unicode(12, (unsigned char) val);
        if (unicode!=-1)
          tab.m_leaderCharacter=uint16_t(unicode);
        else if (val>0x1f && val<0x80)
          tab.m_leaderCharacter=uint16_t(unicode);
        else {
          f << "###";
          MWAW_DEBUG_MSG(("ReadySetGoStyleManager::readTabulations: unknown tab's leader character\n"));
        }
      }
      tabs.push_back(tab);
    }
    if (vers>3) {
      val=int(input->readLong(4));
      if (val)
        f << "decal[decimal]=" << float(val)/65536;
    }
    ascFile.addPos(pos);
    ascFile.addNote(f.str().c_str());
  }

  input->seek(endPos, librevenge::RVNG_SEEK_SET);
  return true;
}


// vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab:
