/*************************************************************************
 *
 *  $RCSfile: svdio.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: aw $ $Date: 2001/03/02 11:46:36 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SVDIO_HXX
#define _SVDIO_HXX

#ifndef _STREAM_HXX //autogen
#include <tools/stream.hxx>
#endif

////////////////////////////////////////////////////////////////////////////////////////////////////

const char SdrIOMagic [2]={'D','r'};
const char SdrIOModlID[2]={'M','d'}; // Model
const char SdrIOItPlID[2]={'I','P'}; // ItemPool
const char SdrIOLayrID[2]={'L','y'}; // Layer
const char SdrIOLSetID[2]={'L','S'}; // Layerset
const char SdrIOPageID[2]={'P','g'}; // Page
const char SdrIOMaPgID[2]={'M','P'}; // MasterPage (Stammseite)
const char SdrIOMPgDID[2]={'M','D'}; // MasterPageDescriptor
const char SdrIOMPDLID[2]={'M','L'}; // MasterPageDescriptorList
const char SdrIOHlpLID[2]={'H','l'}; // HelpLine
const char SdrIOHLstID[2]={'H','L'}; // HelpLineList
const char SdrIODObjID[2]={'O','b'}; // Object
const char SdrIOConnID[2]={'C','n'}; // ObjConnection (EdgeObj)
const char SdrIOViewID[2]={'V','w'}; // View
const char SdrIOPgVwID[2]={'P','V'}; // PageView
const char SdrIOEndeID[2]={'X','X'}; // Ende
const char SdrIOJoeMagic[4]={'J','o','e','M'}; // Um meine eigenen SubRecords zu erkennen

const nAktSdrFileMajorVersion =  0;

// #84529# increase fileversion to be able to correct gradient rotation for 5.2 and earlierl
const nAktSdrFileMinorVersion = 17; // = 16;

const nAktSdrFileVersion = (nAktSdrFileMajorVersion <<8) + (nAktSdrFileMinorVersion);
const nSdrFileVersion31 = 12; // Fileversion des Office 3.1
const nSdrFileVersion40 = 13; // Fileversion des Office 4.0
const nSdrFileVersion50 = 14; // Fileversion des Office 5.0
const nSdrFileVersion51 = 15; // Fileversion des Office 5.1

// Fileversionen:
//  0= ??-04-1995  Initialversion.
//     24-04-1995  Offizielles Office 3.0 Beta I Shipping
//  1= 25-04-1995  Zus. Flag fuer Layer: Standardlayer (JOE)
//     26-04-1995  AttrObj: Beim Stylesheet-Namen wird zusaetzlich der CharSet gemerkt (SB)
//     28-04-1995  Neu: MasterPageDescriptoren (VisibleLayers f. Masterpages) (JOE)
//  2= 18-05-1995  Drehwinkel und Shearwinkel am Gruppenobjekt (JOE)
//     20-05-1995  EdgeObj nun von TextObj statt von PathObj abgeleitet (JOE)
//  3= 23-05-1995  Textrahmen werden nun durch RectObj dargestellt (JOE)
//  4= 31-05-1995  Weiteres persistentes Flag am Zeichenobjekt bNotVisibleAsMaster (JOE)
//     12-06-1995  Offizielles Office 3.0 Beta II Shipping
//     13-06-1996  bTextToContour raus und durch Item ersetzt (JOE)
//     14-06-1996  SdrItemPool muss nun ohne RefCounts geladen werden (JOE)
//  5= 14-06-1995  SdrOutlinerSetItem als neuer Member im SdrAttrObj (JOE)
//  6= 28-06-1995  Neue Items: pMiscAttr; -> Eckenradius-Member entfaellt am RectObj (JOE)
//  6= 30-06-1995  Neuer Member am SdrGrafObj: aCropRect (JOE)
//  6= 07-07-1995  Neue Items fuer Fontwork am XOutDev (ESO)
//     10-07-1995  Office 3.0 Beta III Shipping an IBM
//  7= 18-07-1995  PolyObj raus, Import am PathObj
//  8= 25-07-1995  GrafObj: zus. Member: aFileName fuer FileLinks
//  9= 02-08-1995  GrafObj: zus. Member: aFilterName fuer FileLinks
//     14-10-1995  Office 3.0 PreRelease fuer Systems Muenchen
//     21-10-1995  Final Office 3.0 Shipping
// 10= 25-10-1995  *pFormTextBoundRect wird gestreamt; Neue Attribute: TextVAdjust, Textabstaende
//     09-11-1995  entgueltiges Format V10 durch erneute Poolumstellung (ExtraPool raus)
// 11= 10-11-1995  - Nicht rueckwaertskompatibel!
//                 - Einfuehrung von Major/MinorVers.
//                 - Aufraeumer: Datensack am Obj f. Konnektoren,...
//                 - bMirrored und aName fuer GrafikObjekt
//                 - DownCompat fuer Grosses, Komplexes und Unbekanntes:
//                   - SdrObject:
//                     - Konnektoren (Flag davor)
//                     - UserDataList (Flag davor)
//                       - UserData
//                   - SdrTextObj:
//                     - OutlinerParaObject (Flag war schon davor)
//                   - SdrPathObj:
//                     - PathPolygon
//                   - SdrEdgeObj:
//                     - EdgeTrack
//                     - Connections haben nun einen eigenen IOHeader
//                   - SdrGrafObj:
//                     - Graphic (Flag davor)
//                     - zus. Flag fuer HasGraphicLink
//                   - SdrOle2Obj:
//                     - Graphic (Flag war schon da)
//                   - SdrModel:
//                     - DocInfo
//                     - DocStatistic (Platz reserviert)
//                     - Misc eingepackt
//                   - SdrPage:
//                     - Misc eingepackt
//                 - Kennung fuer SubRecord meines Model und meiner Page (JoeMagic)
//                 - SvdAttrObj: CharSet fuer StyleSheet entfaellt
//                 - CharSet weg bei SdrModel und SdrAttrObj
//                 - WhichId's weg bei SdrAttrObj und SdrCaptionObj
// 12= 05-12-1995  Neues Item: SdrTextHorzAdjustItem. Textverankerung an Textrahmen und
//                 Grafikobjekten. Beim Import von <V12 werden Grafikobjekte hart attributiert.
//     12-02-1996  UIScale und UIUnit wird vom Model nun rausgeschrieben
//     16-02-1996  Shipping des Office 3.00.2 (SV304a)
//     29-02-1996  Pool V3: 17 neue Items im XOut von KA fuer Bitmapfuellungen
//     13-03-1996  Version fuer CeBit 96
//  ca 15-04-1996  Shipping Version 3.1
//     10-08-1996  Pool Version 4; eigene Items am Verbinder
//     28-08-1996  CeBIT Home
//     21-01-1997  EdgeObj: EdgeInfo und Attribute
// 13= 05-02-1997  Fuer Franz's Dateiformatsumstellungen an der 3D-Engine
// 14= 13-03-1998  Fuer FmFormPage (FormLayer)
// 15= 19-01-1999  Fuer StarDraw-Preview
// 16= 25-08-1999  SdrPage background object

class SvStream;

class SdrIOHeader 
{
protected:
	// 10 Bytes persistent:
	char						cMagic[2];
	char						cHdrID[2];

	// Versionsnummer des Blocks
	UINT16						nVersion;    

	// Gesamtgroesse des Blocks inkl. Header und verschachtelten Bloecken
	UINT32						nBlkSize;    

	// ab hier Verwaltungsinformationen:
	SvStream&					rStream;
	UINT32						nFilePos;
	UINT16						nMode;
	BOOL						bOpen;
	BOOL						bClosed;
	// Header wird nur zum nachschauen verwendet.
	BOOL						bLookAhead; 

	virtual void Write();
	virtual void Read();

#if 0 // _SOLAR__PRIVATE
#ifdef DBG_UTIL
	void ImpCheckRecordIntegrity();
	void ImpGetRecordName(ByteString& rStr, INT32 nSubRecCount=-1, INT32 nSubRecReadCount=-1) const;
	BOOL ImpHasSubRecords() const;
#endif
#endif // __PRIVATE

public:
	SdrIOHeader(SvStream& rNewStream, UINT16 nNewMode, const char cID[2]=SdrIOEndeID, BOOL bAutoOpen=TRUE);
	virtual ~SdrIOHeader();

	BOOL IsMagic() const { return cMagic[0] == SdrIOMagic[0] && cMagic[1] == SdrIOMagic[1];  }
	void SetMagic() { cMagic[0] = SdrIOMagic[0]; cMagic[1] = SdrIOMagic[1]; }
	BOOL IsEnde() const { return cHdrID[0] == SdrIOEndeID[0] && cHdrID[1] == SdrIOEndeID[1]; }
	void SetEnde() { cHdrID[0] = SdrIOEndeID[0]; cHdrID[1] = SdrIOEndeID[1]; nBlkSize = 0; SetMagic(); }
	BOOL IsID(const char cID[2]) const { return cHdrID[0] == cID[0] && cHdrID[1] == cID[1]; }
	void SetID(const char cID[2]) { cHdrID[0] = cID[0]; cHdrID[1] = cID[1]; SetMagic(); }
	UINT16 GetVersion() const { return nVersion; }
	UINT16 GetMinorVersion() const { return nVersion | 0xFF; }
	UINT16 GetMajorVersion() const { return nVersion >>8; }
	UINT32 GetFilePos() const { return nFilePos; }
	UINT32 GetBlockSize() const { return nBlkSize; }
	void OpenRecord();
	void CloseRecord();
	UINT32 GetBytesLeft() const;
};

class SdrIOHeaderLookAhead: public SdrIOHeader 
{
public:
	SdrIOHeaderLookAhead(SvStream& rNewStream, BOOL bAutoOpen = TRUE);
	void SkipRecord() const { rStream.Seek(nFilePos+nBlkSize); }
};

/*
I/O-Format (12+n Bytes)
 4 Inventor
 2 Version
 2 Identifier
 4 Menge der nachfolgenden Daten in Bytes
-------
 2 Layer
16 Allumschliessendes Rechteck
 n>=18 Objektspezifische Daten
*/
//const SdrObjIOHeaderSize=6;

class SdrObject;

class SdrObjIOHeader: public SdrIOHeader 
{
public:
	// ab hier persistente Daten
	UINT32						nInventor;
	UINT16						nIdentifier;

	// ab hier Verwaltungsinformationen
	const SdrObject*			pObj;

protected:
	virtual void Write();
	virtual void Read();

public:
	SdrObjIOHeader(SvStream& rNewStream, UINT16 nNewMode, const SdrObject* pNewObj = NULL, BOOL bAutoOpen = TRUE);

	// DTor ueberladen, den in Dtor von SdrIOHeader lebt der SdrObjIOJHeader nicht mehr.
	virtual ~SdrObjIOHeader();
};

class SdrObjIOHeaderLookAhead: public SdrObjIOHeader 
{
public:
	SdrObjIOHeaderLookAhead(SvStream& rNewStream, BOOL bAutoOpen = TRUE);
	void SkipRecord() const { rStream.Seek(nFilePos+nBlkSize); }
};

// Klasse fuer Abwaertskompatibilitaet (Lesen neuer Daten mit altem Code)
// In der Regel reicht es aus, diese Klasse am Anfang des Lese/Schreibfokus
// auf dem Stack mit bAutoOpen=TRUE (default) zu instanziieren. Der Rest
// geschieht von selbst. Will man am Ende des Lesens wissen, ob noch weitere
// Daten im Sub-Record enthalten sind, ruft man GetBytesLeft().
// Den SubRecord schliesst man entweder mit CloseSubRecord() oder man laesst
// ihn vom Destruktor automatisch schliessen.
// Dieses Konzept setzt jedoch eine feste Reihenfolge und Anzahl der SubRecords
// voraus.
class SdrDownCompat 
{
protected:
	SvStream&					rStream;
	UINT32						nSubRecSiz;
	UINT32						nSubRecPos;
	UINT16						nMode;
	BOOL						bOpen;
	BOOL						bClosed;

	// nur fuer Debug
	const char*					pRecId; 

protected:
	virtual void Read();
	virtual void Write();

public:
	// Als Modus muss STREAM_READ oder STREAM_WRITE angegeben werden.
	SdrDownCompat(SvStream& rNewStream, UINT16 nNewMode, BOOL bAutoOpen = TRUE);
	~SdrDownCompat();

#ifdef DBG_UTIL
	// fuer etwas aussagekraeftigere Assertions
	void SetID(const char* pId) { pRecId=pId; }
#endif

	// Mit GetBytesLeft() kann man abfragen, ob und wieviele Bytes noch
	// im SubRecord stehen. Nur gueltig bei STREAM_READ, sonst 0.
	// Nach CloseRecord() liefert diese Methode auch im Modus STREAM_READ 0.
	// (Denn dann sind die restlichen Bytes bereits uebersprungen.)
	UINT32 GetBytesLeft() const;
	BOOL IsOpen() const { return bOpen; }

	// Die Pos ist erst gueltig nach Open bzw nach CTor mit bAutoOpen=TRUE.
	UINT32 GetSubRecordPos() const { return nSubRecPos; }

	// Erst gueltig nach Open bzw. nach CTor mit bAutoOpen=TRUE.
	// Beim Modus STREAM_WRITE ist die Size erst nach Close() gueltig.
	UINT32 GetSubRecordSize() const { return nSubRecSiz; }
	void  OpenSubRecord();
	void  CloseSubRecord();
};

// Identifier fuer SdrNamedSubRecord bei Inventor==SdrInventor
enum {SDRIORECNAME_VIEWPAGEVIEWS   =0x0000,  // alle Pageviews, angezeigte und nicht angezeigte
	  SDRIORECNAME_VIEWVISIELEM    =0x0001,  // sichtbare Elemente (Seite, Rand, Gitter, Hilfslinien,...)

	  SDRIORECNAME_VIEWSNAP        =0x0010,  // Fangeinstellungen
	  SDRIORECNAME_VIEWORTHO       =0x0011,  // Einstellungen fuer Ortho

	  SDRIORECNAME_VIEWDRAGMODE    =0x0020,  // Move oder Rotate/Slant/..., bEditMode, RefPoints, FramDragSingles, PlusAlways
	  SDRIORECNAME_VIEWMARKEDOBJ   =0x0021,  // (ni) markierte Objekte
	  SDRIORECNAME_VIEWMARKEDPNT   =0x0022,  // (ni) markierte Punkte
	  SDRIORECNAME_VIEWCROOKCENTER =0x0023,  // Kreismittelpunkt des letzten Crook
	  SDRIORECNAME_VIEWMARKEDGLUE  =0x0024,  // (ni) markierte Klebepunkte

	  SDRIORECNAME_VIEWDRAGSTRIPES =0x0030,  // Animierte Begrenzungslinien waerend des Draeggens
	  SDRIORECNAME_VIEWDRAGHIDEHDL =0x0031,  // Handles waerend des Draeggens verstecken
	  SDRIORECNAME_VIEWDRAGEDGES   =0x0032,  // (ni) Einstellungen fuer EdgeDragging
	  SDRIORECNAME_VIEWOBJHITMOVES =0x0033,  // Bei MarkedHit Move oder DragMode
	  SDRIORECNAME_VIEWMIRRDRAGOBJ =0x0034,  // Obj beim schieben der Spiegelachse zeigen

	  SDRIORECNAME_VIEWCROBJECT    =0x0040,  // Aktuelles CreateObj
	  SDRIORECNAME_VIEWAKTLAYER    =0x0041,  // Layer fuer Create und Paste (nun in der PaintView)
	  SDRIORECNAME_VIEWCRATTRIBUTES=0x0042,  // (ni) Attribute fuer Create
	  SDRIORECNAME_VIEWCRSTYLESHEET=0x0043,  // (ni) StyleSheet fuer Create
	  SDRIORECNAME_VIEWCRFLAGS     =0x0044,  // Misc Flags fuer Create

	  SDRIORECNAME_VIEWTEXTEDIT    =0x0050,  // Div. Einstellungen fuer TextEdit
	  SDRIORECNAME_VIEWMACRO       =0x0051,  // Div. Einstellungen fuer Macro

	  SDRIORECNAME_VIEWCHARSET     =0x0080,  // Hier merkt sich die SdrView den CharSet und setzt diesem beim Read am Stream

	  SDRIORECNAME_PAGVIEW         =0x0100,  // Pageview sichtbar, Seitennummer, Position, Ursprung
	  SDRIORECNAME_PAGVLAYER       =0x0101,  // angezeigte, gesperrte und druckbare Layer
	  SDRIORECNAME_PAGVHELPLINES   =0x0102,  // Hilfslinien und -punkte
	  SDRIORECNAME_PAGVAKTGROUP    =0x0103,  // (ni) aktuelle Gruppe

	  SDRIORECNAME_MARK            =0x0200,  // (ni)

	  SDRIORECNAME_USERDEFINEDFIRST=0x7000,
	  SDRIORECNAME_USERDEFINEDLAST =0x7FFF};

class SdrNamedSubRecord: public SdrDownCompat 
{
	UINT32						nInventor;
	UINT16						nIdentifier;

protected:
	virtual void Read();
	virtual void Write();

public:
	SdrNamedSubRecord(SvStream& rNewStream, UINT16 nNewMode,
		UINT32 nNewInventor = 0xFFFF, UINT16 nNewIdentifier = 0xFFFF,
		BOOL bAutoOpen = TRUE);
	UINT32 GetInventor() const { return nInventor; }
	UINT16 GetIdentifier() const { return nIdentifier; }
};

// Zum Speichern einer View habe ich ein etwas anderes Konzept gewaehlt, da
// sich das Dateiformat hier sicherlich haeufiger und aufwendiger aendert.
// Es werden eine Anzahl von SdrNamedSubRecords geschrieben, wobei jeder
// dieser Records bestimmte Teilinformationen enthaelt, z.B. die Menge der
// sichtbaren Layer einer Page oder den Default-Stylesheet fuer neu zu
// erzeugende Objekte, ... . Diese Konzept hat zwar einen groesseren Overhead
// an Verwaltung und Daten zur Folge, bietet dafuer jedoch eine sehr grosse
// Flexibilitaet im Punkte auf-/abwaertskompatibilitaet. Da die Menge der
// persistenten Daten einer View recht gering ist spielt der Overhead an
// Streamdaten kaum eine Rolle.
// Eine abgeleitete View ueberlaed die Methoden ReadRecord() (lesen eines
// einzelnen Records) und WriteRecords() (schreiben aller Records). Ein Muster
// ist in SdrSnpV.CXX zu finden.

// Folgende Methoden schauen nach, ob sich im Stream an der aktuellen Position
// ein SdrModel bzw. eine SdrView befindet. Hat der Stream einen Fehlerstatus
// oder Eof(), so wird FALSE returniert.
BOOL SdrIsModel(SvStream& rIn);
BOOL SdrIsView(SvStream& rIn);

#endif //_SVDIO_HXX

/* /////////////////////////////////////////////////////////////////////////////////////////////////

IO-Datenstruktur:

Ú---------¿     Ú----¿               Ú----¿
| SdrData | --->´ModlÃ-Â----->----Â->´EndeÃ--->
À---------Ù     À----Ù   Ú----¿    À----Ù
					   À<-´ViewÃ<-Ù
						  À----Ù

Ú------¿         Ú-------¿   Ú-------¿  Ú--------¿                Ú----¿
| Modl |     --->´ModlHdrÃ-->´ModlDatÃ->´ItemPoolÃ->Â----->----Â->´EndeÃ--->
À------Ù         À-------Ù   À-------Ù  À--------Ù    Ú----¿    À----Ù
													Ã<-´LayrÃ<-´
													|  À----Ù  |
													  Ú----¿  
													Ã<-´LSetÃ<-´
													|  À----Ù  |
													  Ú----¿  
													À<-´PageÃ<-Ù
													   À----Ù

Ú--------¿       Ú-----------¿   Ú-----------¿
|ItemPool|   --->´ItemPoolHdrÃ-->´SfxItemPoolÃ--->
À--------Ù       À-----------Ù   À-----------Ù

Ú------¿         Ú-------¿   Ú-------¿                Ú--------¿
| Page |     --->´PageHdrÃ-->´PageDatÃ->Â----->----Â->´DObjListÃ--->
À------Ù         À-------Ù   À-------Ù    Ú----¿    À--------Ù
										Ã<-´LayrÃ<-´
										|  À----Ù  |
										  Ú----¿  
										À<-´LSetÃ<-Ù
										   À----Ù

Ú----------¿                     Ú----¿
| DObjList | --->Â------>-----Â->´EndeÃ--->
À----------Ù       Ú------¿    À----Ù
				 À<-´ DObj Ã<-Ù
					À------Ù

Ú------¿         Ú-------¿   Ú-------¿
| DObj |     --->´DObjHdrÃ-->´DObjDatÃ-->Â------>-------Â--->
À------Ù         À-------Ù   À-------Ù     Ú--------¿  
										 À->´DObjListÃ->Ù
											À--------Ù
Ú------¿         Ú-------¿   Ú-------¿
| Layr |     --->´LayrHdrÃ-->´LayrDatÃ--->
À------Ù         À-------Ù   À-------Ù

Ú------¿         Ú-------¿   Ú-------¿
| LSet |     --->´LSetHdrÃ-->´LSetDatÃ--->
À------Ù         À-------Ù   À-------Ù

Ú------¿         Ú-------¿   Ú-------¿
| View |     --->´ViewHdrÃ-->´ViewDatÃ--->
À------Ù         À-------Ù   À-------Ù

///////////////////////////////////////////////////////////////////////////////////////////////// */

