function JForm(id, o) {
    $.extend(this, o);
    this.controls = id;
    this.drawGroup($("<table></table>").appendTo(id), this.fields);
    this.refresh();
}

$.extend(JForm.prototype, {
    fields  : [],
    display : {},
    values  : {},

    drawGroup: function (id, group) {
        if (group instanceof Array) {
            var controlbox, that = this,
                addField = function(f) { return function () { that.drawField(id, f); that.refresh(); }; };
            for (var i=0,f; f = group[i]; i++) {
                if (f.show || !f.repeat) { this.drawField(id, f); }
                if (f.repeat) {
                    controlbox = controlbox || $("<div class='controls'></div>").insertAfter(id);
                    $("<span class='add'>" + f.title + "</span>")
                        .addClass(f.id)
                        .appendTo(controlbox)
                        .click(addField(f));
                }
            }
        }
    },

    drawField: function (id, field) {
        // Normally, each field has an <input/>. If there is a list of values, use <select>. If the field has a group, add a <table> for those fields
        var tag  = field.group ? "table" : field.values ? "select" : "input";
        var opt = [];
        for (var v in field.values) { if (field.values.hasOwnProperty(v)) { opt.push("<option value='", v, "'>", field.values[v], "</option>"); } }
        var title = field.href ? ["<a target='help' class='greybox' href='", field.href, "'>", field.title, "</a>"].join("") : field.title;
        var row = [ "<tr class='", field.id, "'><td class='label'>", title, "</td><td class='field'><", tag, " ", field.attr || "", " class='", field.id, "' value='", field.value || "", "'>", opt.join(""), "</", tag, "></td></tr>" ].join("");
/* TODO: Implement color picker and slider */

        // If the element passed is a <table>, append. Else, assume it's a <tr>, and insert after it.
        var fieldnode = (id[0].nodeName.match(/table/i) ? $(row).appendTo(id) : $(row).insertAfter(id)).find(tag + "." + field.id);
        this.drawGroup(fieldnode, field.group);

        var that = this,
            label = fieldnode.parent().prev();
        if (field.repeat) {
            $("<span class='add button'>+</span>"      ).addClass(field.id).prependTo(label).click(function () { that.drawField($(this).parents("tr").eq(0), field); that.refresh(); });
            $("<span class='del button'>&times;</span>").addClass(field.id).prependTo(label).click(function () { $(this).parents("tr").eq(0).remove(); that.refresh(); });
        }
        fieldnode.filter("input,select").change(function() { that.refresh(); });
    },

    refresh: (function() {
        // Hide or show buttons depending on the number of repeats
        function hideButtons(context, field) {
            if (field instanceof Array) {
                for (var i=0,f; f=field[i]; i++) {
                    if (f.repeat || f.group) {
                        var newcontext = $("tr." + f.id, context);
                        if (f.repeat) { if (f.repeat <= newcontext.length) { $(".add." + f.id, context).hide(); } }
                        if (f.group)  { newcontext.each(function() { hideButtons($(this), f.group); }); }
                    }
                }
            }
        }

        return function () {
            // Show all buttons
            $(".add").show();

            // Show / Hide fields
            var cache = {}, show = {}, that = this;
            for (var i=0,rule; rule=this.display[i]; i++) {
                var q = rule.q;
                if (typeof cache[q] == "undefined") { cache[q] = that.match(q)[0] || ""; }
                // if (rule.f(cache[q])) { $("." + rule.id, this.controls).show(); } else { $("." + rule.id).hide(); }
                show[rule.id] = rule.f(cache[q]);
            }

            $("tr,span", this.controls).each(function() {
                var el = $(this), c = el.attr("class").split(" ");
                for (var i=0,cl; cl=c[i]; i++) {
                    if (cl in show) { if (show[cl]) { el.show(); } else { el.hide(); } }
                }
            });

            // Hide buttons that are not required
            hideButtons(this.controls, this.fields);
            if (typeof this.onrefresh == "function") { this.onrefresh(this.getvalues()); }
        };
    })(),

    // Returns hash of computed values that are visible and non-null
    getvalues: function() {
        var val = {};
        for (var id in this.values) { if (this.values.hasOwnProperty(id)) {
            var v = this.values[id],
                out = v.f(this.match(v.q));
            if (out.match(/\w/)) { val[id] = out; }
        } }
        return val;
    },

    // Returns array of field values matching the selector (or array of selectors)
    // "cht" gets all input.cht or select.cht under tr.cht
    // "chs:[x]x[y]" matches all tr.chs and within each, finds input.x or selector.x and replaces [x] with that value
    match: (function() {
        // Returns values of first input / select under element having class cls. <select multiple> gets comma-separated values
        // Ignore hidden values
        var val = function(element, cls) {
            var s = $(element).find("input." + cls + ",select." + cls).val();
            if (s instanceof Array) { s = s.join(","); }
            return s;
        };

        var isVisible = function () {
            var el = $(this);
            return el.css("display") != "none" && el.parents(":hidden").length === 0;
        };

        var domatch = function(q) {
            var pattern = q.split(":"),
                cls = pattern.shift(),
                s = pattern ? pattern.join(":") : "",
                el = $("tr." + cls).filter(isVisible),
                that = this;
            return s ? el.map(function(i,v) { return s.replace(/\[(.*?)\]/g, function(m,cls) { return cls ? val(v, cls) : i; }); }).get()
                     : el.map(function(i,v) {                                                  return       val(v, cls);         }).get();
        };

        return function(q) {
            if (q instanceof Array) {
                var o = domatch(q[0]);
                for (var i=1,e; e=q[i]; i++) { o.push.apply(o, domatch(e)); }
                return o;
            }
            else { return domatch(q); }
        };
    })()
});


$(function() {
    window.gc = new JForm("#main", {
        fields:[
            { id:"cht", title:"Type", href:"http://code.google.com/apis/chart/#chart_type", value:"bvs", values:{
                "lc" :"Line chart"             ,
                "lxy":"XY chart"               ,
                "ls" :"Sparkline"              ,
                "bhs":"Bar: horizontal stacked",
                "bvs":"Bar: vertical stacked"  ,
                "bhg":"Bar: horizontal grouped",
                "bvg":"Bar: vertical grouped"  ,
                "p"  :"Pie: 2D"                ,
                "p3" :"Pie: 3D"                ,
                "v"  :"Venn diagram"           ,
                "s"  :"Scatterplot"            ,
                "r"  :"Radar"                  ,
                "rs" :"Radar spline"           ,
                "t"  :"Map"                    ,
                "gom":"Google-o-meter"         } },

            { id:"chs", title:"Size", href:"http://code.google.com/apis/chart/#chart_size", group:[
                { id:"x", title:"X", value:"300" },
                { id:"y", title:"Y", value:"200" } ] },

            { id:"chtt", title:"Title", href:"http://code.google.com/apis/chart/#chtt", value:"Title" },

/* TODO: Support other encodings */
            // { id:"enc", title:"Encoding", value:"t", values:{ "t":"Text", "s":"Simple", "e":"Extended"} },
            // { id:"enc", title:"Encoding", href:"http://code.google.com/apis/chart/#text", value:"t", values:{ "t":"Text" } },

            { id:"datasets",   title:"Data", value:"", repeat:100, show:1, group:[
                { id:"chd",    title:"Values",    href:"http://code.google.com/apis/chart/#chart_data", value:"5,10,20,40,80" },
                { id:"basics", title:"Basics",    href:"http://code.google.com/apis/chart/#linechartlines", repeat:1, group:[
                    { id:"chl",    title:"Label",     href:"http://code.google.com/apis/chart/#pie_labels", value:"" },
                    { id:"chdl",   title:"Name",        href:"http://code.google.com/apis/chart/#chdl", value:"" },
                    { id:"chp",    title:"Zero line",   href:"http://code.google.com/apis/chart/#chp", value:"" },
                    { id:"chco",   title:"Color",       href:"http://code.google.com/apis/chart/#line_bar_pie_colors", value:"b9a0ff" } ] },
                { id:"line",   title:"Line",    href:"http://code.google.com/apis/chart/#linechartlines", repeat:1, group:[
                    { id:"chls_t", title:"Thickness",   value:"1" },
                    { id:"chls_l", title:"Line width",  value:"1" },
                    { id:"chls_b", title:"Blank width", value:"0" } ] },
                { id:"chm_ls", title:"Line", repeat:1, href:"http://code.google.com/apis/chart/#barchartlines", group:[
                    { id:"col",  title:"Color", value:"b9a0ff" },
                    { id:"size", title:"Size",  value:"3" },
                    { id:"priority", title:"Priority", value:"0", values:{
                         "1" : "Line above bars and markers",
                         "0" : "Line above bars, below markers",
                        "-1" : "Line below bars and markers" } } ] },
                { id:"chm_fa", title:"Fill",      href:"http://code.google.com/apis/chart/#fill_area_marker", repeat:1, value:"dbdbff" },
                { id:"chds", title:"Scale",     href:"http://code.google.com/apis/chart/#data_scaling", repeat:1, group:[
                    { id:"min", title:"Min", value:"0" },
                    { id:"max", title:"Max", value:"100" } ] },
                { id:"chm_sm", title:"Marker", repeat:100, href:"http://code.google.com/apis/chart/#shape_markers", group:[
                    { id:"point", title:"For point", value:"0" },
                    { id:"type", title:"Type", value:"o", values: {
                        "o" : "Circle",
                        "s" : "Square",
                        "c" : "Cross",
                        "d" : "Diamond",
                        "x" : "X shape",
                        "a" : "Arrow",
                        "v" : "Vertical line from bottom",
                        "V" : "Vertical line to top",
                        "h" : "Horizontal line",
                        "t" : "Text" } },
                    { id:"chm_sm_text", title:"Text",     value:"" },
                    { id:"col",      title:"Color",    value:"ff0000" },
                    { id:"size",     title:"Size",     value:"10" },
                    { id:"priority", title:"Priority", value:"0", values: {
                         "1" :  "Line above bars and markers",
                         "0" :  "Line above bars, below markers",
                        "-1" :  "Line below bars and markers" } }
                ] }
            ] },

            { id:"chf", title:"Background", href:"http://code.google.com/apis/chart/#solid_fill", repeat:2, group:[
                { id:"type", title:"Type", value:"s", values: {
                    "s"  : "Solid fill",
                    "lg" : "Linear gradient",
                    "ls" : "Linear strips" } },
                { id:"t", title:"Area", value:"c", values: {
                    "c" : "Chart area fill",
                    "bg": "Background fill",
                    "a" : "Apply transparency" } },
                { id:"angle",   title:"Angle",  value:"0"       },
                { id:"col",     title:"Color",  value:"ffffcc"  },
                { id:"offset",  title:"Offset", value:"0.0"     },
                { id:"width",   title:"Width",  value:"0.2"     },
                { id:"col2",    title:"Color",  value:"ffffff"  },
                { id:"offset2", title:"Offset", value:"1.0"     },
                { id:"width2",  title:"Width",  value:"0.2"     }
            ] },

            { id:"chg", title:"Grid lines", href:"http://code.google.com/apis/chart/#grid", repeat:1, group:[
                { id:"x", title:"X axis step size",        value:"20" },
                { id:"y", title:"Y axis step size",        value:"20" },
                { id:"l", title:"Length of line segment",  value:"1"  },
                { id:"b", title:"Length of blank segment", value:"3"  } ] },

            { id:"chbh", title:"Bar handling", href:"http://code.google.com/apis/chart/#bar_width", group:[
                { id:"w", title:"Bar width",            value:"20" },
                { id:"b", title:"Space between bars",   value:"10" },
                { id:"g", title:"Space between groups", value:"10" } ] },

            { id:"chtm", title:"Geographical area", href:"http://code.google.com/apis/chart/#maps", value:"world", values:{
                "africa"        :"Africa"       ,
                "asia"          :"Asia"         ,
                "europe"        :"Europe"       ,
                "middle_east"   :"Middle East"  ,
                "south_america" :"South America",
                "usa"           :"USA"          ,
                "world"         :"World"        } },

            { id:"axis", title:"Axis", value:"", repeat:10, group:[
                { id:"chxt", title:"Type", href:"http://code.google.com/apis/chart/#axis_type", value:"x", values:{ x:"Bottom X", y:"Left Y", t:"Top X", r:"Right Y" } },
                { id:"chxl", title:"Labels", href:"http://code.google.com/apis/chart/#axes_labels", value:"0,50,100" },
                { id:"chxp", title:"Positions", href:"http://code.google.com/apis/chart/#axes_label_positions", value:"" },
                { id:"chxr", title:"Range", href:"http://code.google.com/apis/chart/#axis_range", repeat:1, group:[
                    { id:"st",  title:"Start", value:"0" },
                    { id:"end", title:"End",   value:"100" } ] },
                { id:"chxs", title:"Style", href:"http://code.google.com/apis/chart/#axes_styles", repeat:1, group:[
                    { id:"c", title:"Color",     value:"777777" },
                    { id:"f", title:"Font",      value:"13" },
                    { id:"a", title:"Alignment", value:"", values: {
                        "0"  : "Centered",
                        "-1" : "Left-aligned",
                        "1"  : "Right-aligned" } } ] } ] },

            { id:"chm_rm", title:"Ranges", href:"http://code.google.com/apis/chart/#hor_line_marker", repeat:100, group:[
                { id:"type", title:"Type",  value:"R", values: { "R": "Vertical", "r": "Horizontal" } },
                { id:"col",  title:"Color", value:"dbdbff" },
                { id:"st",   title:"Start", value:"0.5" },
                { id:"end",  title:"End",   value:"1.0" } ] },

            { id:"chld", title:"Country / State", href:"http://code.google.com/apis/chart/#maps", value:"", attr:"multiple", values:{
                "AF":"Afghanistan"                                  ,
                "AX":"Aland Islands"                                ,
                "AL":"Albania"                                      ,
                "DZ":"Algeria"                                      ,
                "AS":"American Samoa"                               ,
                "AD":"Andorra"                                      ,
                "AO":"Angola"                                       ,
                "AI":"Anguilla"                                     ,
                "AQ":"Antarctica"                                   ,
                "AG":"Antigua And Barbuda"                          ,
                "AR":"Argentina"                                    ,
                "AM":"Armenia"                                      ,
                "AW":"Aruba"                                        ,
                "AU":"Australia"                                    ,
                "AT":"Austria"                                      ,
                "AZ":"Azerbaijan"                                   ,
                "BS":"Bahamas"                                      ,
                "BH":"Bahrain"                                      ,
                "BD":"Bangladesh"                                   ,
                "BB":"Barbados"                                     ,
                "BY":"Belarus"                                      ,
                "BE":"Belgium"                                      ,
                "BZ":"Belize"                                       ,
                "BJ":"Benin"                                        ,
                "BM":"Bermuda"                                      ,
                "BT":"Bhutan"                                       ,
                "BO":"Bolivia"                                      ,
                "BA":"Bosnia And Herzegovina"                       ,
                "BW":"Botswana"                                     ,
                "BV":"Bouvet Island"                                ,
                "BR":"Brazil"                                       ,
                "IO":"British Indian Ocean Territory"               ,
                "BN":"Brunei Darussalam"                            ,
                "BG":"Bulgaria"                                     ,
                "BF":"Burkina Faso"                                 ,
                "BI":"Burundi"                                      ,
                "KH":"Cambodia"                                     ,
                "CM":"Cameroon"                                     ,
                "CA":"Canada"                                       ,
                "CV":"Cape Verde"                                   ,
                "KY":"Cayman Islands"                               ,
                "CF":"Central African Republic"                     ,
                "TD":"Chad"                                         ,
                "CL":"Chile"                                        ,
                "CN":"China"                                        ,
                "CX":"Christmas Island"                             ,
                "CC":"Cocos (Keeling) Islands"                      ,
                "CO":"Colombia"                                     ,
                "KM":"Comoros"                                      ,
                "CD":"Congo"                                        ,
                "CG":"Congo"                                        ,
                "CK":"Cook Islands"                                 ,
                "CR":"Costa Rica"                                   ,
                "CI":"Cote D'Ivoire"                                ,
                "HR":"Croatia"                                      ,
                "CU":"Cuba"                                         ,
                "CY":"Cyprus"                                       ,
                "CZ":"Czech Republic"                               ,
                "DK":"Denmark"                                      ,
                "DJ":"Djibouti"                                     ,
                "DM":"Dominica"                                     ,
                "DO":"Dominican Republic"                           ,
                "EC":"Ecuador"                                      ,
                "EG":"Egypt"                                        ,
                "SV":"El Salvador"                                  ,
                "GQ":"Equatorial Guinea"                            ,
                "ER":"Eritrea"                                      ,
                "EE":"Estonia"                                      ,
                "ET":"Ethiopia"                                     ,
                "FK":"Falkland Islands (Malvinas)"                  ,
                "FO":"Faroe Islands"                                ,
                "FJ":"Fiji"                                         ,
                "FI":"Finland"                                      ,
                "FR":"France"                                       ,
                "GF":"French Guiana"                                ,
                "PF":"French Polynesia"                             ,
                "TF":"French Southern Territories"                  ,
                "GA":"Gabon"                                        ,
                "GM":"Gambia"                                       ,
                "GE":"Georgia"                                      ,
                "DE":"Germany"                                      ,
                "GH":"Ghana"                                        ,
                "GI":"Gibraltar"                                    ,
                "GR":"Greece"                                       ,
                "GL":"Greenland"                                    ,
                "GD":"Grenada"                                      ,
                "GP":"Guadeloupe"                                   ,
                "GU":"Guam"                                         ,
                "GT":"Guatemala"                                    ,
                "GG":"Guernsey"                                     ,
                "GN":"Guinea"                                       ,
                "GW":"Guinea-Bissau"                                ,
                "GY":"Guyana"                                       ,
                "HT":"Haiti"                                        ,
                "HM":"Heard Island And Mcdonald Islands"            ,
                "HN":"Honduras"                                     ,
                "HK":"Hong Kong"                                    ,
                "HU":"Hungary"                                      ,
                "IS":"Iceland"                                      ,
                "IN":"India"                                        ,
                "ID":"Indonesia"                                    ,
                "IR":"Iran"                                         ,
                "IQ":"Iraq"                                         ,
                "IE":"Ireland"                                      ,
                "IM":"Isle Of Man"                                  ,
                "IL":"Israel"                                       ,
                "IT":"Italy"                                        ,
                "JM":"Jamaica"                                      ,
                "JP":"Japan"                                        ,
                "JE":"Jersey"                                       ,
                "JO":"Jordan"                                       ,
                "KZ":"Kazakhstan"                                   ,
                "KE":"Kenya"                                        ,
                "KI":"Kiribati"                                     ,
                "KP":"Korea Democratic People's Republic Of"        ,
                "KR":"Korea Republic Of"                            ,
                "KW":"Kuwait"                                       ,
                "KG":"Kyrgyzstan"                                   ,
                "LA":"Lao People's Democratic Republic"             ,
                "LV":"Latvia"                                       ,
                "LB":"Lebanon"                                      ,
                "LS":"Lesotho"                                      ,
                "LR":"Liberia"                                      ,
                "LY":"Libyan Arab Jamahiriya"                       ,
                "LI":"Liechtenstein"                                ,
                "LT":"Lithuania"                                    ,
                "LU":"Luxembourg"                                   ,
                "MO":"Macao"                                        ,
                "MK":"Macedonia"                                    ,
                "MG":"Madagascar"                                   ,
                "MW":"Malawi"                                       ,
                "MY":"Malaysia"                                     ,
                "MV":"Maldives"                                     ,
                "ML":"Mali"                                         ,
                "MT":"Malta"                                        ,
                "MH":"Marshall Islands"                             ,
                "MQ":"Martinique"                                   ,
                "MR":"Mauritania"                                   ,
                "MU":"Mauritius"                                    ,
                "YT":"Mayotte"                                      ,
                "MX":"Mexico"                                       ,
                "FM":"Micronesia"                                   ,
                "MD":"Moldova"                                      ,
                "MC":"Monaco"                                       ,
                "MN":"Mongolia"                                     ,
                "ME":"Montenegro"                                   ,
                "MS":"Montserrat"                                   ,
                "MA":"Morocco"                                      ,
                "MZ":"Mozambique"                                   ,
                "MM":"Myanmar"                                      ,
                "NA":"Namibia"                                      ,
                "NR":"Nauru"                                        ,
                "NP":"Nepal"                                        ,
                "NL":"Netherlands"                                  ,
                "AN":"Netherlands Antilles"                         ,
                "NC":"New Caledonia"                                ,
                "NZ":"New Zealand"                                  ,
                "NI":"Nicaragua"                                    ,
                "NE":"Niger"                                        ,
                "NG":"Nigeria"                                      ,
                "NU":"Niue"                                         ,
                "NF":"Norfolk Island"                               ,
                "MP":"Northern Mariana Islands"                     ,
                "NO":"Norway"                                       ,
                "OM":"Oman"                                         ,
                "PK":"Pakistan"                                     ,
                "PW":"Palau"                                        ,
                "PS":"Palestinian Territory"                        ,
                "PA":"Panama"                                       ,
                "PG":"Papua New Guinea"                             ,
                "PY":"Paraguay"                                     ,
                "PE":"Peru"                                         ,
                "PH":"Philippines"                                  ,
                "PN":"Pitcairn"                                     ,
                "PL":"Poland"                                       ,
                "PT":"Portugal"                                     ,
                "PR":"Puerto Rico"                                  ,
                "QA":"Qatar"                                        ,
                "RE":"Reunion"                                      ,
                "RO":"Romania"                                      ,
                "RU":"Russian Federation"                           ,
                "RW":"Rwanda"                                       ,
                "BL":"Saint Barthelemy"                             ,
                "SH":"Saint Helena"                                 ,
                "KN":"Saint Kitts And Nevis"                        ,
                "LC":"Saint Lucia"                                  ,
                "MF":"Saint Martin"                                 ,
                "PM":"Saint Pierre And Miquelon"                    ,
                "VC":"Saint Vincent And The Grenadines"             ,
                "WS":"Samoa"                                        ,
                "SM":"San Marino"                                   ,
                "ST":"Sao Tome And Principe"                        ,
                "SA":"Saudi Arabia"                                 ,
                "SN":"Senegal"                                      ,
                "RS":"Serbia"                                       ,
                "SC":"Seychelles"                                   ,
                "SL":"Sierra Leone"                                 ,
                "SG":"Singapore"                                    ,
                "SK":"Slovakia"                                     ,
                "SI":"Slovenia"                                     ,
                "SB":"Solomon Islands"                              ,
                "SO":"Somalia"                                      ,
                "ZA":"South Africa"                                 ,
                "GS":"South Georgia And The South Sandwich Islands" ,
                "ES":"Spain"                                        ,
                "LK":"Sri Lanka"                                    ,
                "SD":"Sudan"                                        ,
                "SR":"Suriname"                                     ,
                "SJ":"Svalbard And Jan Mayen"                       ,
                "SZ":"Swaziland"                                    ,
                "SE":"Sweden"                                       ,
                "CH":"Switzerland"                                  ,
                "SY":"Syrian Arab Republic"                         ,
                "TW":"Taiwan"                                       ,
                "TJ":"Tajikistan"                                   ,
                "TZ":"Tanzania"                                     ,
                "TH":"Thailand"                                     ,
                "TL":"Timor-Leste"                                  ,
                "TG":"Togo"                                         ,
                "TK":"Tokelau"                                      ,
                "TO":"Tonga"                                        ,
                "TT":"Trinidad And Tobago"                          ,
                "TN":"Tunisia"                                      ,
                "TR":"Turkey"                                       ,
                "TM":"Turkmenistan"                                 ,
                "TC":"Turks And Caicos Islands"                     ,
                "TV":"Tuvalu"                                       ,
                "UG":"Uganda"                                       ,
                "UA":"Ukraine"                                      ,
                "AE":"United Arab Emirates"                         ,
                "GB":"United Kingdom"                               ,
                "US":"United States"                                ,
                "UM":"United States Minor Outlying Islands"         ,
                "UY":"Uruguay"                                      ,
                "UZ":"Uzbekistan"                                   ,
                "VU":"Vanuatu"                                      ,
                "VA":"Vatican City"                                 ,
                "VE":"Venezuela"                                    ,
                "VN":"Viet Nam"                                     ,
                "VG":"Virgin Islands British"                       ,
                "VI":"Virgin Islands U.S."                          ,
                "WF":"Wallis And Futuna"                            ,
                "EH":"Western Sahara"                               ,
                "YE":"Yemen"                                        ,
                "ZM":"Zambia"                                       ,
                "ZW":"Zimbabwe"                                     } }
        ],
        onrefresh: function(val) {
            // Construct URL and show it
            var url = [];
            for (var id in val) { if (val.hasOwnProperty(id)) { url.push(id + "=" + val[id]); } }
            url = "http://chart.apis.google.com/chart?" + url.join("&");
            $("img#chart").attr("src", url);
            $("textarea#url").val(url);
        },
        display: [
            { id:"chbh"        , q:"cht"          , f:function(v) { return v.match(/^b/)            ;} },
            { id:"chp"         , q:"cht"          , f:function(v) { return v.match(/^b/)            ;} },
            { id:"chls_t"      , q:"cht"          , f:function(v) { return v.match(/^l/)            ;} },
            { id:"chls_l"      , q:"cht"          , f:function(v) { return v.match(/^l/)            ;} },
            { id:"chls_b"      , q:"cht"          , f:function(v) { return v.match(/^l/)            ;} },
            { id:"chm_ls"      , q:"cht"          , f:function(v) { return v.match(/^b/)            ;} },
            { id:"chm_fa"      , q:"cht"          , f:function(v) { return v.match(/^(l|b|r)/)      ;} },
            { id:"chm_sm"      , q:"cht"          , f:function(v) { return v.match(/^(l|b|r|s)/)    ;} },
            { id:"chm_rm"      , q:"cht"          , f:function(v) { return v.match(/^(l|b|r|s)/)    ;} },
            { id:"chg"         , q:"cht"          , f:function(v) { return v.match(/^(l|b|r|s)/)    ;} },
            { id:"axis"        , q:"cht"          , f:function(v) { return v.match(/^(l|b|r|s)/)    ;} },
            { id:"chdl"        , q:"cht"          , f:function(v) { return v.match(/^(l|b|r|s|v)/)  ;} },
            { id:"chtt"        , q:"cht"          , f:function(v) { return v.match(/^(l|b|r|s|v|p)/);} },
            { id:"chf"         , q:"cht"          , f:function(v) { return v.match(/^(l|b|r|s|v|p)/);} },
            { id:"chl"         , q:"cht"          , f:function(v) { return v.match(/^(gom|p)/)      ;} },
            { id:"chds"        , q:"cht"          , f:function(v) { return v != 't'                 ;} },
            { id:"chtm"        , q:"cht"          , f:function(v) { return v == 't'                 ;} },
            { id:"chld"        , q:"cht"          , f:function(v) { return v == 't'                 ;} },
            { id:"angle"       , q:"chf:[type]"   , f:function(v) { return v == 'lg'                ;} },
            { id:"offset"      , q:"chf:[type]"   , f:function(v) { return v == 'lg'                ;} },
            { id:"offset2"     , q:"chf:[type]"   , f:function(v) { return v == 'lg'                ;} },
            { id:"width"       , q:"chf:[type]"   , f:function(v) { return v == 'ls'                ;} },
            { id:"width2"      , q:"chf:[type]"   , f:function(v) { return v == 'ls'                ;} },
            { id:"col2"        , q:"chf:[type]"   , f:function(v) { return v.match(/^l/)            ;} },
            { id:"chm_sm_text" , q:"chm_sm:[type]", f:function(v) { return v.match(/^t/)            ;} }
        ],
        values: {
            "cht"   : { q:"cht"                , f:function(v) { return v.join(""); } },
            "chs"   : { q:"chs:[x]x[y]"        , f:function(v) { return v.join(""); } },
            "chtt"  : { q:"chtt"               , f:function(v) { return v.join(""); } },
            "chbh"  : { q:"chbh:[w],[b],[g]"   , f:function(v) { return v.join(""); } },
            "chtm"  : { q:"chtm"               , f:function(v) { return v.join(""); } },
            "chxt"  : { q:"chxt"               , f:function(v) { return v.join(","); } },
            "chdl"  : { q:"chdl"               , f:function(v) { return v.join("|"); } },
            "chds"  : { q:"chds:[min],[max]"   , f:function(v) { return v.join(","); } },
            "chco"  : { q:"chco"               , f:function(v) { return $.map(v, function(e) { return e.replace(/,/g, "|"); }).join(","); } },
            "chp"   : { q:"chp"                , f:function(v) { return v.join(","); } },
            "chxp"  : { q:"chxp:[],[chxp]"     , f:function(v) { return v.join("|"); } },
            "chxr"  : { q:"chxr:[],[st],[end]" , f:function(v) { return v.join("|"); } },
            "chxs"  : { q:"chxs:[],[c],[f],[a]", f:function(v) { return v.join("|"); } },
            "chg"   : { q:"chg:[x],[y],[l],[b]", f:function(v) { return v[v.length-1] || ""; } },
            "chxl"  : { q:"chxl:[]:|[chxl]"    , f:function(v) { return v.join("|").replace(/,/g, "|"); } },
            "chl"   : { q:"chl"                , f:function(v) { return v.join("|").replace(/,/g, "|"); } },
            "chld"  : { q:"chld"               , f:function(v) { return v.join(",").replace(/,/g, "" ); } },
            "chd"   : { q:"chd"                , f:function(v) { return "t:" + v.join("|"); } },
            "chls"  : { q:"line:[chls_t],[chls_l],[chls_b]", f:function(v) { return v.join("|"); } },
/* TODO: chm_sm dataset hardcoded to 0 */
            "chm"   : { q:[ "chm_fa:B,[chm_fa],[],0,0",
                            "chm_ls:D,[col],[],0,[size],[priority]",
                            "chm_sm:[type][chm_sm_text],[col],0,[point],[size],[priority]",
                            "chm_rm:[type],[col],0,[st],[end]" ],
                        f:function(v) { return $.grep(v, function(x) { return !x.match(/,,/) && x; }).reverse().join("|"); } },
            "chf"   : { q:"chf:[type]|[t],s,[col]|[t],lg,[angle],[col],[offset],[col2],[offset2]|[t],ls,[col],[width],[col2],[width2]",
                        f:function(v) {
                            return $.map(v, function(v,i) {
                                var l=v.split(/\|/);
                                return l[0]=="s" ? l[1] : l[0]=="lg" ? l[2] : l[0]=="ls" ? l[3] : "";
                            }).join("|");
                      } }
        }
    });
});










/* Greybox Redux
 * Required: http://jquery.com/
 * Written by: John Resig
 * Based on code by: 4mir Salihefendic (http://amix.dk)
 * License: LGPL (read more in LGPL.txt)
 * http://jquery.com/demo/grey/
 */

$(function() {
    var GB_DONE = false,
        GB_HEIGHT = 400,
        GB_WIDTH = 400,
        gb_hide = function() { $("#GB_window,#GB_overlay").hide(); },
        gb_position = function () {
            var de = document.documentElement;
            var w = self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
            $("#GB_window").css({width:GB_WIDTH+"px", height:GB_HEIGHT+"px", left: ((w - GB_WIDTH)/2)+"px" });
            $("#GB_frame").css("height",GB_HEIGHT +"px");
        };

    function gb_show(caption, url, height, width) {
        GB_HEIGHT = height || 400;
        GB_WIDTH = width || 400;
        if(!GB_DONE) {
            $(document.body)
              .append("<div id='GB_overlay'></div><div id='GB_window'><div id='GB_caption'></div><iframe id='GB_frame'></iframe>"
                + "<img src='../i/close.png' alt='Close window'/></div>");
            $("#GB_window img").click(gb_hide);
            $("#GB_overlay").click(gb_hide);
            $(window).resize(gb_position);
            GB_DONE = true;
        }

        $("#GB_window").show();
        setTimeout(function() {
            $("#GB_frame").attr("src", url);
            $("#GB_caption").html(caption);
            $("#GB_overlay").show();
            gb_position();
        }, 0);
    }

    $(document.body).click(function(e){
        var el = $(e.target), href = el.attr("href");
        if (el.hasClass("greybox") && href) { gb_show("Help", href, 400, 700); e.preventDefault(); }
    });

    $(this.url).click(function() { $(this).select(); });
});

