
TMainFrm ---+--- TSdiEdOptions (record)
            |
            |
            +--- TCoreEngine ---+--- TBackgroundEngine
            |                   |
            |                   |
            |                   +--- TUndoEngine --- TUndoItem []
            |                   |
            |                   |
            |                   +--- TToolOptions
            |
            |
            +--- TTool*


(capitalization in CamelCase usually means it's an internal identifier, not
just a name)

The topmost component is form, which owns everything else.

Options hold application's config - which colours to use when highlighting,
how fast is scrolling and so on. Whenever it changes, it is passed to engine
and from there further. Due to rather messy nature of its "tree" (record of
records), individual recipients down the line must do their own diffing to
understand what has changed.

CoreEngine contains the picture itself and offers a set of tools for painting,
caching and syncing with viewport. Typically, painting happens on its Overlay
bitmap and will be flushed to main picture (Picture) when finished, by calling
CommitOverlay. It is also preferable that tools access user-visible canvas and
other interfaces for temporary drawing through Viewport property of engine.

BackgroundEngine wraps the logic needed for handling all kinds of backgrounds
along with caching and lazy updating. From outside, it needs as inputs only
config (Options) and what the user can select on background form. To outside it
offers just a function that gives a bitmap for mode. It does *not* handle
backgrounds' list management!

UndoEngine is relatively tightly connected to CoreEngine. It is never accessed
from outside on low enough level to see the actual workings; the only interfaces
meant for usage are undo/redo (further unspecified) and status properties. On
low level, AddStep method is automatically called with each CommitOverlay and
in turn creates a new UndoItem, which is then responsible for retrieving and
eventually applying data. This division of responsibilities actually makes
UndoEngine only a dumb container that just ensures correct order of individual
UndoItems and oversees their invokes.

Tools are semi-temporary objects which handle the logic of particular kinds of
image manipulation. Eg. when a painting tool is used, it starts its internal
action when left mouse button is held down and finishes when it goes up. Tools
draw on engine's Overlay and then commit it or discard. Additionally they can
draw "temporary description" such as brush shape directly on Viewport.

All configuration of tools happens through engine's ToolOptions, since tools
can exist alone and can not be all collected. Due to the very same reason,
tools do not get any change notifications and rather re-read information from
their parent engine's ToolOptions on the fly.
