#ifndef ORCAD_READ_PARSE_H
#define ORCAD_READ_PARSE_H

/* types shall hold AT LEAST the specified amount of bits (i.e. */
/* orcad_uint16_t must be at least 16-bits wide) */
typedef unsigned char orcad_uint8_t;
typedef signed int    orcad_int16_t;
typedef unsigned int  orcad_uint16_t;
typedef signed long   orcad_int32_t;
typedef unsigned long orcad_uint32_t;

struct io_orcad_rctx_s;
struct orcad_inlinepageobject_node;
struct orcad_symboldisplayprop_node;
struct orcad_ercsymbolinst_node;
struct orcad_prim;

enum orcad_type
{
	ORCAD_TYPE_INLINEPAGEOBJECT   = 0x02,
	ORCAD_TYPE_PROPERTIES         = 0x06,
	ORCAD_TYPE_SCHEMATIC          = 0x09,
	ORCAD_TYPE_PAGE               = 0x0a,
	ORCAD_TYPE_PARTINST           = 0x0d,
	ORCAD_TYPE_PINCONNECTION      = 0x10,
	ORCAD_TYPE_WIRE               = 0x14,
	ORCAD_TYPE_PORT               = 0x17,
	ORCAD_TYPE_SYMBOLGRAPHIC      = 0x18,
	ORCAD_TYPE_SYMBOLPIN          = 0x1a,
	ORCAD_TYPE_SYMBOLPINMAPPING   = 0x1f,
	ORCAD_TYPE_PINIDXMAPPING      = 0x20,
	ORCAD_TYPE_GLOBALSYMBOL       = 0x21,
	ORCAD_TYPE_PORTSYMBOL         = 0x22,
	ORCAD_TYPE_OFFPAGECONNSYMBOL  = 0x23,
	ORCAD_TYPE_GLOBAL             = 0x25,
	ORCAD_TYPE_OFFPAGECONN        = 0x26,
	ORCAD_TYPE_SYMBOLDISPLAYPROP  = 0x27,
	ORCAD_TYPE_ALIAS              = 0x31,
	ORCAD_TYPE_NETPROP            = 0x34,
	ORCAD_TYPE_BUSPROP            = 0x35,
	ORCAD_TYPE_GRAPHICBOXINST     = 0x37,
	ORCAD_TYPE_GRAPHICLINEINST    = 0x38,
	ORCAD_TYPE_GRAPHICARCINST     = 0x39,
	ORCAD_TYPE_GRAPHICELLIPSEINST = 0x3a,
	ORCAD_TYPE_GRAPHICPOLYGONINST = 0x3b,
	ORCAD_TYPE_GRAPHICTEXTINST    = 0x3d,
	ORCAD_TYPE_GRAPHICBITMAPINST  = 0x3e,
	ORCAD_TYPE_TITLEBLOCKSYMBOL   = 0x40,
	ORCAD_TYPE_TITLEBLOCK         = 0x41,
	ORCAD_TYPE_ERCSYMBOL          = 0x4b,
	ORCAD_TYPE_BOOKMARKSYMBOL     = 0x4c,
	ORCAD_TYPE_ERCSYMBOLINST      = 0x4d,
	ORCAD_TYPE_BOOKMARKSYMBOLINST = 0x4e,
	ORCAD_TYPE_GRAPHICBEZIERINST  = 0x58,

	/* additional types that are not part of the binary format */

	ORCAD_TYPE_X_NETALIAS         = 0x1000,
	ORCAD_TYPE_X_CACHE            = 0x1001,
	ORCAD_TYPE_X_SYMBOLGROUP      = 0x1002,
	ORCAD_TYPE_X_CACHESYMBOL      = 0x1003,
	ORCAD_TYPE_X_CACHESYMVARIANT  = 0x1004,
	ORCAD_TYPE_X_LIBRARY          = 0x1010
};

enum orcad_primtype
{
	ORCAD_PRIMITIVE_RECT          = 0x28,
	ORCAD_PRIMITIVE_LINE          = 0x29,
	ORCAD_PRIMITIVE_ARC           = 0x2a,
	ORCAD_PRIMITIVE_ELLIPSE       = 0x2b,
	ORCAD_PRIMITIVE_POLYGON       = 0x2c,
	ORCAD_PRIMITIVE_POLYLINE      = 0x2d,
	ORCAD_PRIMITIVE_TEXT          = 0x2e,
	ORCAD_PRIMITIVE_BITMAP        = 0x2f,
	ORCAD_PRIMITIVE_SYMBOLVECTOR  = 0x30,
	ORCAD_PRIMITIVE_BEZIER        = 0x57
};

typedef struct orcad_graphic_inline
{
	orcad_uint32_t instname_idx; /* name index in 'Library' */
	orcad_uint32_t libpath_idx; /* name index in 'Library' */
	char* name;
	orcad_uint32_t db_id;
	orcad_int16_t  y;
	orcad_int16_t  x;
	orcad_int16_t  y2;
	orcad_int16_t  x2;
	orcad_int16_t  x1;
	orcad_int16_t  y1;
	orcad_uint8_t  color;
	orcad_uint8_t  rotation;
	orcad_uint8_t  mirrored;
	orcad_uint8_t  unknown_2;
	orcad_uint8_t  unknown_3;

	orcad_uint16_t num_displayprops;
	struct orcad_symboldisplayprop_node** displayprops;

	enum orcad_type type;

	struct orcad_inlinepageobject_node* obj;
} orcad_graphic_inline_t;

typedef struct orcad_namemapping
{
	orcad_uint32_t name_idx;
	orcad_uint32_t value_idx;
} orcad_namemapping_t;

struct orcad_namemapping_info
{
	long offs;
	long size;
};

typedef struct orcad_node
{
	enum orcad_type    type;
	struct orcad_node* parent;

	/* offset where the object payload starts */
	long offs;

	/* size of the object according to orcad_header */
	long size;

	struct orcad_namemapping_info nmi;
	orcad_uint16_t num_namemappings;
	struct orcad_namemapping* namemappings;

} orcad_node_t;

typedef struct orcad_alias_node
{
	struct orcad_node node;

	orcad_uint32_t x;
	orcad_uint32_t y;
	orcad_uint32_t color;
	orcad_uint8_t  rotation;
	orcad_uint8_t  mirrored;
	orcad_uint16_t unknown_0;
	orcad_uint16_t font_id;
	orcad_uint16_t unknown_1;
	char* name;
} orcad_alias_node_t;

typedef struct orcad_xnetalias_node
{
	struct orcad_node node;

	char* alias;
	orcad_uint32_t net_id;
} orcad_xnetalias_node_t;

typedef struct orcad_symboldisplayprop_node
{
	struct orcad_node node;

	orcad_uint32_t name_idx;
	orcad_int16_t  x;
	orcad_int16_t  y;
	orcad_uint16_t font_id;
	orcad_uint8_t  rotation;
	orcad_uint8_t  color;
	orcad_uint8_t  unknown_0;
	orcad_uint8_t  format;
	orcad_uint8_t  unknown_2;

#define ORCAD_SYMBOLDISPLAYPROP_FORMAT__VALUE_ONLY              0x01
#define ORCAD_SYMBOLDISPLAYPROP_FORMAT__NAME_AND_VALUE          0x02
#define ORCAD_SYMBOLDISPLAYPROP_FORMAT__NAME_ONLY               0x03
#define ORCAD_SYMBOLDISPLAYPROP_FORMAT__BOTH_IF_VALUE_EXISTS    0x04

} orcad_symboldisplayprop_node_t;

struct orcad_netprop_node
{
	struct orcad_node node;

	orcad_uint32_t net_id;
	orcad_uint8_t  unknown[7];
	orcad_uint32_t color;
	orcad_uint32_t line_width;
	orcad_uint32_t line_style;
};

struct orcad_busprop_node
{
	struct orcad_node node;

	orcad_uint32_t net_id;
	orcad_uint8_t  unknown[7];
	orcad_uint32_t color;
	orcad_uint32_t line_width;
	orcad_uint32_t line_style;

	orcad_uint16_t num_busnetids;
	orcad_uint32_t* busnetids;
};

typedef struct orcad_wire_node
{
	struct orcad_node node;

/* TODO: wire_id__to__net_id*/
	orcad_uint32_t wire_id;
	orcad_uint32_t net_id;
	orcad_uint32_t color;
	orcad_uint32_t start_x;
	orcad_uint32_t start_y;
	orcad_uint32_t end_x;
	orcad_uint32_t end_y;
	orcad_uint8_t  unknown_0; /* related to junctions */

	orcad_uint16_t num_aliases;
	struct orcad_alias_node** aliases;

	orcad_uint16_t num_displayprops;
	struct orcad_symboldisplayprop_node** displayprops;

	orcad_uint32_t line_width;
	orcad_uint32_t line_style;
} orcad_wire_node_t;

typedef struct orcad_titleblock_node
{
	struct orcad_node node;

	orcad_uint32_t unknown_0;
	orcad_uint32_t unknown_1;

	char* name; /* i.e. "TitleBlock0" */

	orcad_uint32_t unknown_2;
	orcad_uint32_t unknown_3;
	orcad_uint32_t unknown_4;
	orcad_uint32_t unknown_5;
	orcad_uint16_t unknown_6;
	orcad_uint16_t unknown_7;

	orcad_uint16_t num_displayprops;
	struct orcad_symboldisplayprop_node** displayprops;

	orcad_uint8_t  unknown_8; /* maybe type? contains 0x40 */
	orcad_uint32_t unknown_9;
	orcad_uint32_t unknown_10;
	orcad_uint32_t unknown_11;
} orcad_titleblock_node_t;

typedef struct orcad_inlinepageobject_node
{
	struct orcad_node node;

	char* name;
	char* unk_str;
	orcad_uint32_t color;

	orcad_uint16_t num_primitives;
	struct orcad_prim** primitives;
} orcad_inlinepageobject_node_t;

typedef struct orcad_port_node
{
	struct orcad_node node;
	struct orcad_graphic_inline graphic;

	orcad_uint32_t wire_id;
	orcad_uint8_t  unknown_0;
	orcad_uint32_t unknown_1;
} orcad_port_node_t;

typedef struct orcad_global_node
{
	struct orcad_node node;
	struct orcad_graphic_inline graphic;

	orcad_uint32_t wire_id;
	orcad_uint8_t  unknown_0;
} orcad_global_node_t;

typedef struct orcad_offpageconn_node
{
	struct orcad_node node;
	struct orcad_graphic_inline graphic;

	orcad_uint32_t wire_id;
	orcad_uint8_t  unknown_0;
} orcad_offpageconn_node_t;

typedef struct orcad_graphicinst_node
{
	struct orcad_node node;
	struct orcad_graphic_inline graphic;
} orcad_graphicinst_node_t;

typedef struct orcad_pinconnection_node
{
	struct orcad_node node;

	orcad_int16_t  nc; /* pin is no connect */
	orcad_int16_t  idx;
	orcad_uint16_t x;
	orcad_uint16_t y;
	orcad_int32_t  wire_id; /* 0 means no wire connected; negative for pin-pin connection */
	orcad_uint32_t net_id;

	orcad_uint16_t num_displayprops;
	struct orcad_symboldisplayprop_node** displayprops;
} orcad_pinconnection_node_t;

typedef struct orcad_partinst_node
{
	struct orcad_node node;

	orcad_uint32_t instname_idx; /* name index in 'Library' */
	orcad_uint32_t libpath_idx; /* name index in 'Library' */
	char* name;
	orcad_uint32_t db_id;
	orcad_int16_t  x1;
	orcad_int16_t  y1;
	orcad_int16_t  x2;
	orcad_int16_t  y2;
	orcad_int16_t  x;
	orcad_int16_t  y;
	orcad_uint8_t  color;
	orcad_uint8_t  rotation;
	orcad_uint8_t  mirrored;
	orcad_uint16_t unknown_4;

	orcad_uint16_t num_displayprops;
	struct orcad_symboldisplayprop_node** displayprops;

	orcad_uint8_t unknown_5;
	char* refdes;
	orcad_uint32_t value_idx; /* name index in 'Library' */
	orcad_uint16_t unknown_7;
	orcad_uint16_t unknown_8;
	orcad_uint32_t unknown_9;
	orcad_uint16_t flags;
	orcad_uint8_t  primitive; /* 0: no; 1: yes; 2: default -- derived from 'flags' */
	orcad_uint8_t  power_pins_visible; /* derived from 'flags' */

	orcad_uint16_t num_pinconnections;
	struct orcad_pinconnection_node** pinconnections;

	char* symname;
	orcad_uint16_t pim_idx; /* pinidxmapping index */

} orcad_partinst_node_t;

struct orcad_pagesettings
{
	orcad_uint32_t ctime;
	orcad_uint32_t mtime;
	orcad_uint32_t unknown_0;
	orcad_uint32_t unknown_1;
	orcad_uint32_t unknown_2;
	orcad_uint32_t unknown_3;
	orcad_uint32_t width;  /* sheet width in mils */
	orcad_uint32_t height; /* sheet height in mils */
	orcad_uint32_t pin_to_pin;
	orcad_uint16_t unknown_4;
	orcad_uint16_t horiz_count; /* this is the resolution of the guides at */
	orcad_uint16_t vert_count;  /* ... the edge of the page */
	orcad_uint16_t unknown_5; /* some flags? */
	orcad_uint32_t horiz_width; /* maybe grid resolution? */
	orcad_uint32_t vert_width;  /* maybe grid resolution? */
	orcad_uint32_t unknown_6;
	orcad_uint32_t unknown_7;
	orcad_uint32_t unknown_8;
	orcad_uint32_t unknown_9;
	orcad_uint32_t unknown_10;
	orcad_uint32_t unknown_11;
	orcad_uint32_t unknown_12;
	orcad_uint32_t unknown_13;
	orcad_uint32_t unknown_14;
	orcad_uint32_t unknown_15;
	orcad_uint32_t unknown_16;
	orcad_uint32_t unknown_17;
	orcad_uint32_t horiz_char;
	orcad_uint32_t unknown_18;
	orcad_uint32_t horiz_ascending;
	orcad_uint32_t vert_char;
	orcad_uint32_t unknown_19;
	orcad_uint32_t vert_ascending;
	orcad_uint32_t is_metric;
	orcad_uint32_t border_displayed;
	orcad_uint32_t border_printed;
	orcad_uint32_t gridref_displayed;
	orcad_uint32_t gridref_printed;
	orcad_uint32_t titleblock_displayed;
	orcad_uint32_t titleblock_printed;
	orcad_uint32_t ansi_grid_refs;
};

typedef struct orcad_page_node
{
	struct orcad_node node;

	char* page_name;
	char* page_size;

	struct orcad_pagesettings settings;

	orcad_uint16_t num_titleblocks;
	struct orcad_titleblock_node** titleblocks;

	orcad_uint16_t num_netprops;
	struct orcad_netprop_node** netprops;

	orcad_uint16_t num_busprops;
	struct orcad_busprop_node** busprops;

	orcad_uint16_t num_netaliases;
	struct orcad_xnetalias_node** netaliases;

	orcad_uint16_t num_wires;
	struct orcad_wire_node** wires;

	orcad_uint16_t num_partinsts;
	struct orcad_partinst_node** partinsts;

	orcad_uint16_t num_ports;
	struct orcad_port_node** ports;

	orcad_uint16_t num_globals;
	struct orcad_global_node** globals;

	orcad_uint16_t num_offpageconns;
	struct orcad_offpageconn_node** offpageconns;

	orcad_uint16_t num_ercsymbolinsts;
	struct orcad_ercsymbolinst_node** ercsymbolinsts;

	orcad_uint16_t num_busentries;

	orcad_uint16_t num_graphicinsts;
	struct orcad_graphicinst_node** graphicinsts;

	orcad_uint16_t num_unk10;

	orcad_uint16_t num_unk11;
} orcad_page_node_t;

struct orcad_symbol_common
{
	char* name;
	char* source;
};

struct orcad_titleblocksymbol_node
{
	struct orcad_node node;
	struct orcad_symbol_common sym_common;

	orcad_uint16_t unknown_0;
	orcad_uint16_t unknown_1;

	orcad_uint16_t num_primitives;
	struct orcad_prim** primitives;

	orcad_uint16_t unknown_2;
	orcad_uint16_t unknown_3;

	orcad_uint16_t num_symbolpins;
	struct orcad_symbolpin_node** symbolpins;

	orcad_uint16_t num_displayprops;
	struct orcad_symboldisplayprop_node** displayprops;
};

typedef struct orcad_symbolgraphic_node
{
	struct orcad_node node;
	struct orcad_symbol_common sym_common;

	orcad_uint16_t unknown_0;
	orcad_uint16_t unknown_1;

	orcad_uint16_t num_primitives;
	struct orcad_prim** primitives;

	orcad_uint16_t symbox_x; /* bbox of symbol primitives */
	orcad_uint16_t symbox_y;

	orcad_uint16_t num_symbolpins;
	struct orcad_symbolpin_node** symbolpins;

	orcad_uint16_t num_displayprops;
	struct orcad_symboldisplayprop_node** displayprops;

	char* unk_str0;
	char* unk_str1;
	char* sym_prefix;
	char* unk_str2;

	orcad_uint16_t flags;
	orcad_uint8_t  pin_names_visible;   /* 0x1 */
	orcad_uint8_t  pin_names_rotate;    /* 0x2 */
	orcad_uint8_t  pin_numbers_visible; /* !0x4 */

} orcad_symbolgraphic_node_t;

typedef struct orcad_properties_node
{
	struct orcad_node node;
	struct orcad_symbol_common sym_common;

	orcad_uint16_t num_partnames;
	char** partnames;
} orcad_properties_node_t;

typedef struct orcad_symbolpinmapping_node
{
	struct orcad_node node;
	struct orcad_symbol_common sym_common;

	char* sym_prefix;
	char* unk_str0;
	char* unk_str1; /* maybe footprint? */

	orcad_uint16_t num_pinidxmappings;
	struct orcad_pinidxmapping_node** pinidxmappings;
} orcad_symbolpinmapping_node_t;

typedef struct orcad_globalsymbol_node
{
	struct orcad_node node;
	struct orcad_symbol_common sym_common;

	orcad_uint16_t unknown_0;
	orcad_uint16_t unknown_1;

	orcad_uint16_t num_primitives;
	struct orcad_prim** primitives;

	orcad_uint16_t symbox_x;
	orcad_uint16_t symbox_y;

	orcad_uint16_t num_symbolpins;
	struct orcad_symbolpin_node** symbolpins;

	orcad_uint16_t num_displayprops;
	struct orcad_symboldisplayprop_node** displayprops;

} orcad_globalsymbol_node_t;
typedef struct orcad_globalsymbol_node orcad_offpageconnsymbol_node_t;
typedef struct orcad_globalsymbol_node orcad_portsymbol_node_t;

typedef struct orcad_symbolpin_node
{
	struct orcad_node node;

	char* pin_name;
	orcad_int32_t start_x;
	orcad_int32_t start_y;
	orcad_int32_t hotpt_x;
	orcad_int32_t hotpt_y;
	orcad_uint16_t pin_shape;
	orcad_uint16_t unknown_0;
	orcad_uint32_t port_type;
	orcad_uint16_t unknown_1;
	orcad_uint16_t unknown_2;

	orcad_uint16_t num_displayprops;
	struct orcad_symboldisplayprop_node** displayprops;

} orcad_symbolpin_node_t;

typedef struct orcad_ercsymbol_node
{
	struct orcad_node node;
	struct orcad_symbol_common sym_common;

	orcad_uint16_t unknown_0; /* perhaps color+rotation */
	orcad_uint16_t unknown_1;

	orcad_uint16_t num_primitives;
	struct orcad_prim** primitives;

	orcad_int16_t x1;
	orcad_int16_t y1;
	orcad_int16_t x2;
	orcad_int16_t y2;
	orcad_int16_t x;
	orcad_int16_t y;

} orcad_ercsymbol_node_t;

typedef struct orcad_ercsymbolinst_node
{
	struct orcad_node node;
	struct orcad_graphic_inline graphic;

	char* msg1;
	char* msg2;
	char* msg3;

} orcad_ercsymbolinst_node_t;

typedef struct orcad_pin
{
	char* pin_name;
	int pin_group; /* negative if pin in an empty group */
	orcad_uint8_t pin_ignore;
} orcad_pin_t;

typedef struct orcad_pinidxmapping_node
{
	struct orcad_node node;

	char* unit_ref;
	char* symname;

	orcad_uint16_t num_pins;
	struct orcad_pin** pins; /* note: some of 'pins[i]' might be NULL! */
} orcad_pinidxmapping_node_t;

typedef struct orcad_schematic_node
{
	struct orcad_node node;

	char* sch_name;
	orcad_uint32_t unknown_0;

	orcad_uint16_t num_pagenames;
	char** pagenames;

	orcad_uint16_t num_unk4s;
	orcad_uint32_t* unk4s;

	orcad_uint16_t num_unk5s;
	unsigned char* unk5s; /* note: each unk5 is 5 bytes wide! */

	orcad_uint32_t unknown_1;

} orcad_schematic_node_t;

typedef struct orcad_xcachesymvariant_node
{
	struct orcad_node node;

	char* lib_path;

	orcad_uint32_t ctime;
	orcad_uint32_t mtime;
	orcad_uint8_t  type;

	struct orcad_node* obj;
} orcad_xcachesymvariant_node_t;

typedef struct orcad_xcachesymbol_node
{
	struct orcad_node node;

	char* symname;

	orcad_uint16_t num_variants;
	struct orcad_xcachesymvariant_node** variants;
} orcad_xcachesymbol_node_t;

typedef struct orcad_xsymbolgroup_node
{
	struct orcad_node node;

	orcad_uint16_t num_symbols;
	struct orcad_xcachesymbol_node** symbols;
} orcad_xsymbolgroup_node_t;

typedef struct orcad_xcache_node
{
	struct orcad_node node;

	struct orcad_xsymbolgroup_node* titleblocks;
	struct orcad_xsymbolgroup_node* symbolgraphics;
	struct orcad_xsymbolgroup_node* symbolproperties;
	struct orcad_xsymbolgroup_node* symbolpinmappings;
} orcad_xcache_node_t;

struct orcad_xlibraryfont
{
	orcad_uint32_t height;
	orcad_uint32_t width;
	orcad_uint32_t escapement;
	orcad_uint32_t orientation;
	orcad_uint32_t weight;
	orcad_uint8_t  italic;
	orcad_uint8_t  underline;
	orcad_uint8_t  strikeout;
	orcad_uint8_t  charset;
	orcad_uint8_t  outprecision;
	orcad_uint8_t  clipprecision;
	orcad_uint8_t  quality;
	orcad_uint8_t  pitchandfamily;

	/* this is a C string stored in a 32-byte buffer (thus, orcad can leave
	   garbage in the file!) */
	char facename[32];
};

struct orcad_xlibraryalias
{
	char* alias;
	char* package;
};

typedef struct orcad_xlibrary_node
{
	struct orcad_node node;

	/* this is a C string stored in a 32-byte buffer (thus, orcad can leave
	   garbage in the file!) */
	char introduction[32];

	orcad_uint16_t ver_major;
	orcad_uint16_t ver_minor;

	orcad_uint32_t ctime;
	orcad_uint32_t mtime;

	orcad_uint16_t num_fonts;
	struct orcad_xlibraryfont* fonts;

	/* array of 16-bit integers for unknown purpose */
	orcad_uint16_t num_unks;
	orcad_uint16_t* unks;

	orcad_uint32_t unknown_0;
	orcad_uint32_t unknown_1;

	/* exactly 8 of them */
	char* partfields[8];

	struct orcad_pagesettings settings;

	orcad_uint32_t num_names;
	char** names;

	orcad_uint16_t num_aliases;
	struct orcad_xlibraryalias* aliases;

	orcad_uint32_t flags;
	orcad_uint32_t unknown_3;

	char* sch_name;

} orcad_xlibrary_node_t;

struct orcad_point
{
	orcad_int16_t x;
	orcad_int16_t y;
};

typedef struct orcad_bsegment
{
	struct orcad_point p1;
	struct orcad_point p2;
	struct orcad_point p3;
	struct orcad_point p4;
} orcad_bsegment_t;

typedef struct orcad_prim
{
	enum orcad_primtype type;
	long offs;
} orcad_prim_t;

typedef struct orcad_text_prim
{
	struct orcad_prim prim;

	orcad_int32_t  x;
	orcad_int32_t  y;
	orcad_int32_t  x1;
	orcad_int32_t  y1;
	orcad_int32_t  x2;
	orcad_int32_t  y2;
	orcad_uint16_t font_id;
	orcad_uint16_t unknown_0;
	char*       text;
} orcad_text_prim_t;

typedef struct orcad_bitmap_prim
{
	struct orcad_prim prim;

	orcad_int32_t  x;
	orcad_int32_t  y;
	orcad_int32_t  x1;
	orcad_int32_t  y1;
	orcad_int32_t  x2;
	orcad_int32_t  y2;
	orcad_uint32_t bmp_width;
	orcad_uint32_t bmp_height;
	orcad_uint32_t bmp_datasize;
	unsigned char* bmp_data;
} orcad_bitmap_prim_t;

typedef struct orcad_line_prim
{
	struct orcad_prim prim;

	orcad_int32_t x1;
	orcad_int32_t y1;
	orcad_int32_t x2;
	orcad_int32_t y2;

	int have_line_style; /* line_style and line_width */
	orcad_uint32_t line_style;
	orcad_uint32_t line_width;
} orcad_line_prim_t;

typedef struct orcad_rect_prim
{
	struct orcad_prim prim;

	orcad_int32_t x1;
	orcad_int32_t y1;
	orcad_int32_t x2;
	orcad_int32_t y2;

	int have_line_style; /* line_style and line_width */
	orcad_uint32_t line_style;
	orcad_uint32_t line_width;

	int have_fill_style; /* fill_style and hatch_style */
	orcad_uint32_t fill_style;
	orcad_uint32_t hatch_style;
} orcad_rect_prim_t;

typedef struct orcad_arc_prim
{
	struct orcad_prim prim;

	/*
		[x1, y1], [x2, y2] is the bbox
		[start_x, start_y] is the starting point of the arc
		[end_x, end_y] is the ending point of the arc

		the arc is drawn from start point to end point in CCW direction
	*/

	orcad_int32_t x1;
	orcad_int32_t y1;
	orcad_int32_t x2;
	orcad_int32_t y2;
	orcad_int32_t start_x;
	orcad_int32_t start_y;
	orcad_int32_t end_x;
	orcad_int32_t end_y;

	int have_line_style; /* line_style and line_width */
	orcad_uint32_t line_style;
	orcad_uint32_t line_width;
} orcad_arc_prim_t;

typedef struct orcad_ellipse_prim
{
	struct orcad_prim prim;

	orcad_int32_t x1;
	orcad_int32_t y1;
	orcad_int32_t x2;
	orcad_int32_t y2;

	int have_line_style; /* line_style and line_width */
	orcad_uint32_t line_style;
	orcad_uint32_t line_width;

	int have_fill_style; /* fill_style and hatch_style */
	orcad_uint32_t fill_style;
	orcad_uint32_t hatch_style;
} orcad_ellipse_prim_t;

typedef struct orcad_polygon_prim
{
	struct orcad_prim prim;

	int have_line_style; /* line_style and line_width */
	orcad_uint32_t line_style;
	orcad_uint32_t line_width;

	int have_fill_style; /* fill_style and hatch_style */
	orcad_uint32_t fill_style;
	orcad_uint32_t hatch_style;

	orcad_uint32_t num_points;
	struct orcad_point* points;
} orcad_polygon_prim_t;

typedef struct orcad_polyline_prim
{
	struct orcad_prim prim;

	int have_line_style; /* line_style and line_width */
	orcad_uint32_t line_style;
	orcad_uint32_t line_width;

	orcad_uint32_t num_points;
	struct orcad_point* points;
} orcad_polyline_prim_t;

typedef struct orcad_bezier_prim
{
	struct orcad_prim prim;

	int have_line_style; /* line_style and line_width */
	orcad_uint32_t line_style;
	orcad_uint32_t line_width;

	orcad_uint32_t num_segments;
	struct orcad_bsegment* segments;
} orcad_bezier_prim_t;

typedef struct orcad_symbolvector_prim
{
	struct orcad_prim prim;

	orcad_int16_t x;
	orcad_int16_t y;

	orcad_uint16_t num_primitives;
	struct orcad_prim** primitives;

	char* name;

} orcad_symbolvector_prim_t;

struct orcad_node* orcad_read(struct io_orcad_rctx_s* const rctx);
struct orcad_node* orcad_read_cache(struct io_orcad_rctx_s* const rctx);
struct orcad_node* orcad_read_library(struct io_orcad_rctx_s* const rctx);
struct orcad_node* orcad_read_schematic(struct io_orcad_rctx_s* const rctx);

void orcad_dump(struct orcad_node* const root);
void orcad_free(struct orcad_node* const root);

#endif /* ORCAD_READ_PARSE_H */
