+
+################################################################################
+# Start Output
+
+if ($HTMLOUTPUT) {
+
+?><!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<title>Ardour Lua Bindings</title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<style type="text/css">
+div.header { text-align:center; }
+div.header h2 { margin:0; }
+div.header p { margin:.25em; text-align:center; }
+div.luafooter { text-align:center; font-size:80%; color: #888; margin: 2em 0; }
+#luaref { max-width:60em; margin: 1em auto; }
+
+#luaref h2 { margin:2em 0 0 0; padding:0em; border-bottom: 1px solid black; }
+#luaref h3.cls { margin:2em 0 0 0; padding: 0 0 0 1em; border: 1px dashed #6666ee; }
+#luaref h3.cls abbr { text-decoration:none; cursor:default; }
+#luaref h4.cls { margin:1em 0 0 0; }
+#luaref h3.class { background-color: #aaee66; }
+#luaref h3.enum { background-color: #aaaaaa; }
+#luaref h3.pointerclass { background-color: #eeaa66; }
+#luaref h3.array { background-color: #66aaee; }
+#luaref h3.opaque { background-color: #6666aa; }
+#luaref p { text-align: justify; }
+#luaref p.cdecl { text-align: right; float:right; font-size:90%; margin:0; padding: 0 0 0 1em; }
+#luaref ul.classindex { columns: 2; -webkit-columns: 2; -moz-columns: 2; }
+#luaref div.clear { clear:both; }
+#luaref p.classinfo { margin: .25em 0; }
+#luaref div.code { width:80%; margin:.5em auto; }
+#luaref div.code div { width:45%; }
+#luaref div.code pre { line-height: 1.2em; margin: .25em 0; }
+#luaref div.code samp { color: green; font-weight: bold; background-color: #eee; }
+#luaref div.classdox { padding: .1em 1em; }
+#luaref div.classdox p { margin: .5em 0 .5em .6em; }
+#luaref div.classdox p { margin: .5em 0 .5em .6em; }
+#luaref div.classdox { padding: .1em 1em; }
+#luaref div.classdox p { margin: .5em 0 .5em .6em; }
+#luaref table.classmembers { width: 100%; }
+#luaref table.classmembers th { text-align:left; border-bottom:1px solid black; padding-top:1em; }
+#luaref table.classmembers td.def { text-align:right; padding-right:.5em; white-space: nowrap; }
+#luaref table.classmembers td.decl { text-align:left; padding-left:.5em; white-space: nowrap; }
+#luaref table.classmembers td.doc { text-align:left; padding-left:.6em; line-height: 1.2em; font-size:80%; }
+#luaref table.classmembers td.doc div.dox {background-color:#eee; padding: .1em 1em; }
+#luaref table.classmembers td.doc p { margin: .5em 0; }
+#luaref table.classmembers td.doc p.para-brief { font-size:120%; }
+#luaref table.classmembers td.doc p.para-returns { font-size:120%; }
+#luaref table.classmembers td.doc dl { font-size:120%; line-height: 1.3em; }
+#luaref table.classmembers td.doc dt { font-style: italic; }
+#luaref table.classmembers td.fill { width: 99%; }
+#luaref table.classmembers span.em { font-style: italic; }
+#luaref span.functionname abbr { text-decoration:none; cursor:default; }
+</style>
+</head>
+<body>
+<div class="header">
+<h2>Ardour Lua Bindings</h2>
+<p>
+<a href="#h_classes">Class Documentation</a>
+ |
+<a href="#h_enum">Enum/Constants</a>
+ |
+<a href="#h_index">Index</a>
+</p>
+</div>
+
+<!-- #### SNIP #### !-->
+
+<?php
+
+} else {
+
+?>
+---
+layout: default
+style: luadoc
+title: Class Reference
+---
+
+<p class="warning">
+This documentation is far from complete may be inaccurate and subject to change.
+</p>
+
+<?php
+}
+?>
+
+<div id="luaref">
+
+<?php
+
+################################################################################
+# some general documentation -- should really go elsehere
+
+?>
+
+<h2 id="h_intro">Overview</h2>
+<p>
+The top-level entry point are <?=typelink('ARDOUR:Session')?> and <?=typelink('ArdourUI:Editor')?>.
+Most other Classes are used indirectly starting with a Session function. e.g. Session:get_routes().
+</p>
+<p>
+A few classes are dedicated to certain script types, e.g. Lua DSP processors have exclusive access to
+<?=typelink('ARDOUR:DSP')?> and <?=typelink('ARDOUR:ChanMapping')?>. Action Hooks Scripts to
+<?=typelink('LuaSignal:Set')?> etc.
+</p>
+<p>
+Detailed documentation (parameter names, method description) is not yet available. Please stay tuned.
+</p>
+<h3>Short introduction to Ardour classes</h3>
+<p>
+Ardour's structure is object oriented. The main object is the Session. A Session contains Audio Tracks, Midi Tracks and Busses.
+Audio and Midi tracks are derived from a more general "Track" Object, which in turn is derived from a "Route" (aka Bus).
+(We say "An Audio Track <em>is-a</em> Track <em>is-a</em> Route").
+Tracks contain specifics. For Example a track <em>has-a</em> diskstream (for file i/o).
+</p>
+<p>
+Operations are performed on objects. One gets a reference to an object and then calls a method.
+e.g <code>obj = Session:route_by_name("Audio") obj:set_name("Guitar")</code>.
+</p>
+<p>
+Lua automatically follows C++ class inheritance. e.g one can directly call all SessionObject and Route methods on Track object. However lua does not automatically promote objects. A Route object which just happens to be a Track needs to be explicily cast to a Track. Methods for casts are provided with each class. Note that the cast may fail and return a <em>nil</em> reference.
+</p>
+<p>
+Likewise multiple inheritance is a <a href="http://www.lua.org/pil/16.3.html">non-trivial issue</a> in lua. To avoid performance penalties involved with lookups, explicit casts are required in this case. One example is <?=typelink('ARDOUR:SessionObject')?> which is-a StatefulDestructible which inhertis from both Stateful and Destructible.
+</p>
+<p>
+Object lifetimes are managed by the Session. Most Objects cannot be directly created, but one asks the Session to create or destroy them. This is mainly due to realtime constrains:
+you cannot simply remove a track that is currently processing audio. There are various <em>factory</em> methods for object creation or removal.
+</p>
+<h3>Pass by Reference</h3>
+<p>
+Since lua functions are closures, C++ methods that pass arguments by reference cannot be used as-is.
+All parameters passed to a C++ method which uses references are returned as Lua Table.
+If the C++ method also returns a value it is prefixed. Two parameters are returned: the value and a Lua Table holding the parameters.
+</p>
+
+<div class="code">
+ <div style="float:left;">C++
+
+<pre><code class="cxx">void set_ref (int& var, long& val)
+{
+ printf ("%d %ld\n", var, val);
+ var = 5;
+ val = 7;
+}
+</code></pre>
+
+ </div>
+ <div style="float:right;">Lua
+
+<pre><code class="lua">local var = 0;
+ref = set_ref (var, 2);
+-- output from C++ printf()
+</code><samp class="lua">0 2</samp><code>
+-- var is still 0 here
+print (ref[1], ref[2])
+</code><samp class="lua">5 7</samp></pre>
+
+ </div>
+</div>
+<div class="clear"></div>
+<div class="code">
+ <div style="float:left;">
+
+<pre><code class="cxx">int set_ref2 (int &var, std::string unused)
+{
+ var = 5;
+ return 3;
+}
+</code></pre>
+
+ </div>
+ <div style="float:right;">
+<pre><code class="lua">rv, ref = set_ref2 (0, "hello");
+print (rv, ref[1], ref[2])
+</code><samp class="lua">3 5 hello</samp></pre>
+ </div>
+</div>
+<div class="clear"></div>
+
+<h3>Pointer Classes</h3>
+<p>
+Libardour makes extensive use of reference counted <code>boost::shared_ptr</code> to manage lifetimes.
+The Lua bindings provide a complete abstration of this. There are no pointers in lua.
+For example a <?=typelink('ARDOUR:Route')?> is a pointer in C++, but lua functions operate on it like it was a class instance.
+</p>
+<p>
+<code>shared_ptr</code> are reference counted. Once assigned to a lua variable, the C++ object will be kept and remains valid.
+It is good practice to assign references to lua <code>local</code> variables or reset the variable to <code>nil</code> to drop the ref.
+</p>
+<p>
+All pointer classes have a <code>isnil ()</code> method. This is for two cases:
+Construction may fail. e.g. <code><?=typelink('ARDOUR:LuaAPI')?>.newplugin()</code>
+may not be able to find the given plugin and hence cannot create an object.
+</p>
+<p>
+The second case if for <code>boost::weak_ptr</code>. As opposed to <code>boost::shared_ptr</code> weak-pointers are not reference counted.
+The object may vanish at any time.
+If lua code calls a method on a nil object, the interpreter will raise an exception and the script will not continue.
+This is not unlike <code>a = nil a:test()</code> which results in en error "<em>attempt to index a nil value</em>".
+</p>
+<p>
+From the lua side of things there is no distinction between weak and shared pointers. They behave identically.
+Below they're inidicated in orange and have an arrow to indicate the pointer type.
+Pointer Classes cannot be created in lua scripts. It always requires a call to C++ to create the Object and obtain a reference to it.
+</p>
+
+
+<?php
+
+#################################
+# Main output function -- Classes
+
+echo '<h2 id="h_classes">Class Documentation</h2>'.NL;
+foreach ($classlist as $ns => $cl) {
+ $dups = array ();
+ $tbl = format_class_members ($ns, $cl, $dups);
+
+ # format class title - depending on type
+ if (empty ($tbl)) {
+ # classes with no members (no ctor, no methods, no data)
+ echo '<h3 id="'.htmlentities ($ns).'" class="cls opaque"><abbr title="Opaque Object">∅</abbr> '.htmlentities ($ns).'</h3>'.NL;
+ }
+ else if (isset ($classlist[$ns]['free'])) {
+ # free functions (no class)
+ echo '<h3 id="'.htmlentities ($ns).'" class="cls freeclass"><abbr title="Namespace">ℕ</abbr> '.ctorname($ns).'</h3>'.NL;
+ }
+ else if (isset ($classlist[$ns]['arr'])) {
+ # C Arrays
+ echo '<h3 id="'.htmlentities ($ns).'" class="cls array"><abbr title="C Array">⋯</abbr> '.htmlentities ($ns).'</h3>'.NL;
+ }
+ else if (isset ($classlist[$ns]['ptr'])) {
+ # Pointer Classes
+ echo '<h3 id="'.htmlentities ($ns).'" class="cls pointerclass"><abbr title="Pointer Class">↠</abbr> '. htmlentities ($ns).'</h3>'.NL;
+ }
+ else {
+ # Normal Class
+ echo '<h3 id="'.htmlentities ($ns).'" class="cls class"><abbr title="Class">∁</abbr> '.htmlentities ($ns).'</h3>'.NL;
+ }
+
+ # show original C++ declaration
+ if (isset ($cl['cdecl'])) {
+ echo '<p class="cdecl"><em>C‡</em>: '.htmlentities ($cl['cdecl']).'</p>'.NL;