If you are going to be working on gpa is very important that you read this document,
you are going to have a hard time trying to figure out how it all ties up together
just by looking at the code, you'll find the code very abstract in this regard so
make sure you undrestand the roles of the different objects in GPA before digging
into the code. 

gpa is a small library (less the 5,000 lines of code) but a lot of the information
is held in the meanings of their objects and links between one another.

GPANode
=======
Every object inside gpa is is derived from the GPANode base class. All of the
objects have an id associated with them and are attached to a tree, the root of
this tree is the GPARoot node (see Root, Config & Globals below). This id allows
us to get access to any node in the tree. For example, to get the selected
paper size, we can do something like:

GPANode *paper_width;
GPANode *root_node;
gchar *width;

root_node = gpa_root_get ();
paper_width = gpa_node_lookup (root_node, "Settings.Output.Media.PhysicalSize.Width");
width = gpa_node_get_value (paper_width);
gpa_node_unref (paper_width);
gpa_node_unref (root_node);
g_print ("The paper width is %s\n", paper_width);
g_free (paper_width);

This method is abstracted on the gnome-print layer by gnome-print-config calls
and a set of defined keys for it, so if an application was interested in the
Paper width, it could do:

gboolean success;
gdouble width;
success = gnome_print_config_get_length (gpc, GNOME_PRINT_KEY_PAPER_WIDTH,
                                         &width, NULL);

This also mean that we can replace the configuration system under gnome-print
with something different than gpa if needed.

Tools
=====
Visualizing the Tree or a subsets of it is going to be very helpfull in understanding
gpa. Using the gpa-dump test program inside libgnomeprint/tests will allow you
to do so. gpa-dump with no arguments dumps the
complete tree without following references to the console. you can specify as
as an argument a node to use as the starting point, for example you can do:

./gpa-dump Globals.Media

to dump the contents of the Globals.Media node. To follow references, you can
specify a maximum depth in which references will be followed with --follow=#.
For example "--follow=2" will follow references if the node is at level 2
or above. See References bellow to understan what references are used for.

I will usually trow in inside the code a "gpa_utils_dump_tree" call followed
by exit(1) for debugging and has proved very usefull.

Printer
=======
This three objects match up their real life mening very closely. A GPAPrinter is
an object that glues together a printer model with selected Settings for it. A GPAPrinter
represents what a user will view as a "configured printer" on his system. Printers
hold very little information, if you look at the _GPAPrinter structure you'll see
that it glues together a Name, a Model and a List of settings. For example a printer
instance can be:

GPAPrinter {
		 GPANode.id = CUPS-PsPrinter
		 GPANode *name = (GPAValue*) "My brother's Postscript printer"
		 GPANode->model = (GPAReference to a GPAModel*) CUPS-HP-Laserjet4MP
		 GPANode->settings = (GPAList*) List of GPASettings objects
		 };

Model
=====		 
A GPAModel describes the capabilities and options of a Printer, it holds information
like the resolutions supported by the printer, the paper trays available to print
from or the supported paper sizes.

Dynamic options like duplex or stapling which might or might not be available in
the same printer & model appear static from gpa's perspective. The models are created
on the fly and this options are enalbed or disabled when the model is created.
Stapling or duplexing capabitlities can be optional in some models, or not available
at a particular moment, say for example the printer has ran out of staples to use.

Making models dynamic should not be hard to do either, it is just a limitation set
forth by the current implementation, the issue here is that a Model is static and
does not hold any state information, it is just descriptive.

Settings
========
The Settings object hold the state or selected options at a given point, they are
an instance of a the capabilities of a Model attached to a printer. Where as a
Model can say "the supported paper sizes are A4,A5,Letter & Legal" settings hold
which of those paper sizes is active or selected.

The settings member of GPAPrinter holds a list of settings attached to it, gpa is designed
so that multiple settings can be held by a printer and allow the user to have
settings for printing "Photographs" or "Drafts" or any other grouping that he
decides to use. Multiple settings are not supported by gnome-print at this time
(Dec,2002) and the "Default" settings (that is the node id) is always used, this
of course, is expected to be supported by GnomePrint in the future.

References
==========
GPAReferences are nodes used to point to other nodes, for example the "model"
member of GPAPrinter is a GPARefernce to a GPAModel, it does not own the model
subtree itself, it just points to it. 

Options & Keys
==============
Options and Keys describe the capabilities of the printers, print job or document
information etc. Options describe the capability and Keys hold the state or selection
of the opiton. Options are attached to Models where as Keys are attached to
Settings.

Other options, that are not specific to a model of a printer, are held
under the "Globals" node of the root node. Examples of such options are
LogicalOrientation, Layouts or the Document subtree. The "Document" options
are those which those options that are not tied to a particular printer like
the Page layout, Orientation, Name of the document, prefered unit, etc.

When a GPASetting is initialized, keys are created for each option in the GPAModel
and for global options. The setting will contain things like PaperSize=A4 which
was created from an option of the GPAModel or Orientation=Landscape which was created
from an option of the Document tree.

       Descriptive             State
       -----------             -----

      GPAModel->options --
                         |____ GPASetting
			          |
      GPARoot->globals  --

[GPAOptions]                        [GPAKeys]
PhysicalSize=A4,A5,USLetter,USLegal  PhysicalSize = A4
LogicalOrientation=R0,R90,R180,R270  LogicalOrientation = R90 (Landscape)

Options and keys can be of different type, each type FIXME>...

- Node
- Key
- List
- Item
  Has a name to be displayed in the gui
- String

FIXME: Explain what each type is used for, refer to gpa_option_verify.

Lists & Values
==============
FIXME:
List and values are used for general strucutre, list of settings
values are used for name nodes.

Root, Config & Globals
======================
FIXME:
Root is the parent of all objects. Contains ->globals, ->printer & ->models
Config is a configuration for a print job, a 
Globals are ... globals

Value
=====
Only used for the name nodes for model and printer (to be depecated soon)

happy hacking,
Chema Celorio (Dec, 2002)

