// vk-view-common:

/*
Syntaxprüfung mit jslint:
java -cp jslint/rhino-1.7.jar \
  org.mozilla.javascript.tools.shell.Main jslint/jslint.js vk-view-common.js
*/

/*jslint newcap: false */
/*global $: false, VKQuery: false, vkConfHits: false, alert: false,
  vkConfForms: false, window: false, VKSid: false, setTimeout: false,
  location: false, vkConfEZBURLs: false, vkConfSUBITOURLs: false,
  vkConfZDBURLs: false, vkConfIASLURLs: false,
  VKViewCatsSelTree: false, VKViewCatSel: false, VKViewInfo: false,
  vkConfEzToLink: false, opacUrlGet: false, catIdiEncode: false,
  mt: false, vkConfQueryFields: false, vkConfMatViewEnable: false,
  vkStyles: false
 */

var VKView = function (confP) {
    var that = {},
    conf = confP,
    updateables = [],

    create = function () {
        // alert("VKView["+type+"] create");
    },

    updateableAdd = function (updateable) {
        updateables.push(updateable);
    },

    updateableRemove = function (updateable) {
        var i;
        for (i = 0; i < updateables.length; i += 1) {
            if (updateables[i] === updateable) {
                updateables.splice(i, 1);
                break;
            }
        }
    },

    updateUpdateables = function (args) {
        var i;
        for (i = 0; i < updateables.length; i += 1) {
            updateables[i].update(that, args);
        }
    };

    that.updateableAdd = updateableAdd;
    that.updateableRemove = updateableRemove;
    that.updateUpdateables = updateUpdateables;

    create();

    return (that);
};


var VKStyles = function (conf) {
    var that = VKView(conf),

    styles = conf.styles,

    hasStyle = function (style) {
        var i;
        for (i = 0; i < styles.length; i += 1) {
            if (styles[i] === style) {
                return (true);
            }
        }
        return (false);
    },

    urlPart = function () {
        var i, up = '';
        for (i = 0; i < styles.length; i += 1) {
            up += '&style=' + styles[i];
        }
        return (up);
    };

    that.hasStyle = hasStyle;
    that.urlPart = urlPart;

    return (that);
};


var VKViewLang = function (conf) {
    var that = VKView(conf),
    cnt,
    create = function () {
        var html, i, k, ks, s;
        ks = conf.lang.keys();
        if (ks.length <= 1) {
            return;
        }
        html =
        '<div class="vkBox ' + conf.lang.dir() +  '" name="vkLang">' + '\n' +
        conf.lang.tag('Sprache:') + '\n' +
        '<select>' + '\n';
        k = conf.lang.key();
        for (i = 0; i < ks.length; i += 1) {
            s = (ks[i] === k) ? ' selected="selected"' : '';
            html +=
                '<option' + s + '>' + ks[i] + '<\/option>' + '\n';
        }
        html +=
        '<\/select>' + '\n' +
        '<\/div>' + '\n';
        conf.cnt.append($(html));
        cnt = $("div[name=vkLang]", conf.cnt);
        $("select", conf.cnt).bind('change select', function (event) {
                var lang = $("option[selected]", this).text();
                conf.lang.set(lang);
            });
        conf.lang.updateableAdd(that);
    },
    vk_delete = function () {
        cnt.remove();
    },
    update = function (src, args) {
        var hint, lang;
        hint = args.hint;
        lang = args.lang;
        if ((hint === "lang") && lang) {
            $("option", cnt).removeAttr("selected");
            $("option", cnt).each(function (n) {
                    if ($(this).text() === lang) {
                        $(this).attr('selected', 'selected');
                    }
                });
        }
    };
    that.create = create;
    that.vk_delete = vk_delete;
    that.update = update;
    create();
    return (that);
};


var VKViewMenu = function (confP) {
    var that = VKView(confP),
    conf = confP,
    lang = confP.lang,
    menuCnt,
    basketCntCnt,
    txts,

    breadcrumbSet = function (mode) {
        var name = (mode === 'simpleSearch') ? 'Einfache Suche'
        : (mode === 'advancedSearch') ? 'Erweiterte Suche'
        : (mode === 'basket') ? 'Merkliste' : '';
        $("span#crumb_last").html(name);
    },

    selectionSet = function (mode) {
        $("a", menuCnt).removeAttr("id");
        $('a[name=' + mode + ']', menuCnt).attr("id", "aktiv2");
        breadcrumbSet(mode);
    },

    onSelect = function () {
        var mode = $(this).attr('name');
        if (mode === 'help') {
            return (true);
        }
        else {
            $("a", menuCnt).removeAttr("id");
            $(this).attr("id", "aktiv2");
            that.updateUpdateables({hint: "menu"});
            breadcrumbSet(mode);
            return (false);
        }
    },

    create = function () {
        var html, tabs;
        tabs = "tabs";
        if (conf.lang.get() === "he") {
            tabs = "right-tabs";
        }
        menuCnt = $("div#navcontainer2");
        selectionSet(conf.mode);
        $("a", menuCnt).click(onSelect);
        txts = lang.attach(menuCnt);
        basketCntCnt = $("a[name=basket] span.cnt", menuCnt);
        conf.basket.updateableAdd(that);
    },
    vk_delete = function () {
        lang.detach(txts);
        conf.basket.updateableRemove(that);
        //menuCnt.remove();
    },
    selectionGet = function () {
        return ($("a#aktiv2", menuCnt).attr("name"));
    },   
    update = function (basket, args) {
        var hits, n;
        hits = conf.basket.hitsGet();
        n = hits.length;
        if (n === 0) {
            basketCntCnt.empty();
        }
        else {
            basketCntCnt.text('(' + n + ')');
        }
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.selectionGet = selectionGet;
    that.update = update;

    create();

    return (that);
};


var VKViewQuerySimple = function (conf) {
    var that = VKView(conf),
    cats = conf.cats,
    query = null,
    container,

    submitEnter = function (event) {
        var form;
        if (event.keyCode === 13) {
            form = $(this).parents().find('form')[0];
            $(form).submit();
            return false;
        }
        else {
            return true;
        }
    },

    update = function (src, args) {
        var hint, queries, query, queryStr;
        hint = args ? (args.hint ? args.hint : "") : "";
        if (hint === 'query-dlg') {
            queryStr = "";
            query = conf.query;
            if (query && query.isSimple()) {
                query = query.get();
                queryStr = query.vals[0];
            }
            $(":text", container).attr("value", queryStr);
        }
        if ((hint !== 'query-history') && (hint !== 'query-history-select')) {
            return;
        }
        if (args.pos === -1) {
            queryStr = "";
        }
        else {
            queries = conf.queryHistory.queriesGet();
            if (queries) {
                query = queries[args.pos];
                if (query) {
                    query = query.get();
                    queryStr = query.vals[0];
                }
            }
        }
        $(":text", container).attr("value", queryStr);
    },

    packageLength = vkConfHits.packageLength,

    searchInSelectedCats = function () {
        var queryStr =
        $("div[name=vkQuerySimple] input[name=query]").attr("value");
        if (queryStr === "") {
            return;
        }
        query = VKQuery({keys: ["all"],
                         vals: [queryStr],
                         ops: [],
                         mats: [],
                         cats: cats.selectedGet()});
        query = conf.queryHistory.add(query);
        // conf.queryHistory.updateUpdateables({hint: "query-history"});
        cats.search({query: query,
                    first: 1,
                    last: packageLength});
        return (false);
    },

    searchReq = function () {
        var queryStr =
        $("div[name=vkQuerySimple] input[name=query]").attr("value");
        if (queryStr === "") {
            alert("Bitte Suchtext eingeben.");
        }
        else {
            searchInSelectedCats();
        }
        return (false);
    },

    create = function () {
        var html, query, queryStr, value;
        html = 
        '<div class="vkBox" name="vkQuerySimple">' +
          '<form class="query" action="#">' +
            '<table>' +
              '<tr>' +
                '<td style="vertical-align: middle;">' +
                  '<input type="text" name="query" value="" size="40" >' +
                  '<input type="button" name="search" value="Suchen" ' +
                         'style="font-size: small">' +
                '<\/td>' +
              '<\/tr>' +
              '<tr>' + 
                '<td>' + 
                 '<span style="font-size: xx-small;">' + 
                  '<a href="#">' + 
                    '[Eingabefeld leeren]' + 
                  '<\/a>' + 
                 '<\/span>' + 
                '<\/td>' + 
              '<\/tr>' + 
            '<\/table>' +
          '<\/form>' +
        '<\/div>';
        conf.container.append($(html));
        container = $("div.vkBox[name=vkQuerySimple]", conf.container);

        $("div[name=vkQuerySimple] a").bind('click', 
                                                              function () {
                $("div[name=vkQuerySimple] input[type=text]").
                    attr("value", "");
                return (false);
            });

        $("div[name=vkQuerySimple] input[name=search]").
          bind('click', searchReq);

        $("div[name=vkQuerySimple] form.query").
          bind('submit', searchReq);

        $("div[name=vkQuerySimple] form.query input:text").
            bind('keypress', submitEnter);

        conf.queryHistory.updateableAdd(that);

        update(that, {hint: "query-dlg"});
        /*
        searchInSelectedCats();
        */
    },

    vk_delete = function () {
        container.remove();
    },

    decode = function (value) {
        return (decodeURIComponent(value));
    },

    hide = function () {
        container.hide();
    },

    queryGet = function () { 
        return (query);
    },

    show = function () {
        container.show();
        $("form.query input:text", container).focus();
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.hide = hide;
    that.queryGet = queryGet;
    that.searchInSelectedCats = searchInSelectedCats;
    that.show = show;
    that.update = update;

    create();

    return (that);
};


var VKViewMat = function (confP) {
    var that = VKView(confP),
    conf = confP,
    container,
    mat,

    update = function (src, args) {
        var i, mats, len, hasMat, f;
        // alert("Update mat");
        if ((args.hint === "query-history") ||
            (args.hint === "query-history-select")) {
            mats = src.sel().matsGet();
            mat.matsSet(mats);
        }
        else if (args.hint !== "mat") {
            return;
        }
        mats = mat.matsGet();
        len = mats.length;
        hasMat = {};
        for (i = 0; i < len; i += 1) {
            hasMat[mats[i]] = true;
        }
        $('input:checkbox', container).each(function () {
                var name = this.name;
                if (name === "any") {
                    if (len) {
                        $(this).removeAttr('checked');
                    }
                    else {
                        $(this).attr('checked', 'checked');
                    }
                }
                else {
                    if (hasMat[name]) {
                        $(this).attr('checked', 'checked');
                    }
                    else {
                        $(this).removeAttr('checked');
                    }
                }
            });
    },

    create = function () {
        var attr, checked, html, i, id, j, name, forms, matInfo;
        mat = conf.mat;
        matInfo = 'Die Namen derjenigen Datenbanken und Kataloge, die die ' +
        'Materialsuche nicht unterstützen, werden nach der Auswahl der ' +
        'entsprechenden Materialart(en) rot hinterlegt.';
        checked = ' checked="checked"';
        html =
        '<table id="vkMat" align="center">' + "\n" +
        '  <tr>' + "\n" +
        '    <td colsspan="2">' + "\n" +
        '      <div class="head">' + "\n" +
        '        <b>Materialart<\/b>' +
        '        &nbsp;<img src="images/help.png" title="' + matInfo + '">'  + 
        '      <\/div>' + "\n" +
        '    <\/td>' + "\n" +
        '  <\/tr>' + "\n";

        forms = [ 'periodical', 'book', 'olper', 'article', 'binary'];

        for (i = -1; i < forms.length;) {
            html +=
                '  <tr>' + "\n";
            for (j = 0; (j < 2) && (i < forms.length); j += 1, i += 1) {
                if (i === -1) {
                    html +=
                        '<td>' + "\n" +
                        '<div class="mat any">' + "\n" +
                        '  <input type="checkbox" name="any">' + "\n" +
                        '  Beliebig' + "\n" +
                        '<\/div>' + "\n" +
                        '<\/td>' + "\n";
                }
                else {
                    id = forms[i];
                    name = vkConfForms[id].name;
                    html +=
                        '<td>' + "\n" +
                        '<div class="mat ' + id + '">' + "\n" +
                        '<input type="checkbox" name="' + id  + '">' + "\n" +
                        '<img src="' + vkConfForms[id].img + '" title="' +
                        name + '" ' +
                        'alt="' + name + '">' + "\n" +
                        name + "\n" +
                        '<\/div>' + "\n" +
                        '<\/td>' + "\n";
                }
            }
            html +=
                '<\/tr>' + "\n";
        }

        html +=
        '<\/table>' + "\n";

        conf.container.append($(html));

        container = $('table#vkMat', conf.container);

        /*
        $("div.sel a.all", container).bind('click', function () {
                $('input:checkbox', conf.container).attr('checked',
                                                            'checked');
                return (false);
            });

        $("div.sel a.none", container).bind('click', function () {
                $('input:checkbox', conf.container).removeAttr('checked');
                return (false);
            });
        */
        $("div input", container).bind('click', function () {
                var name = this.name;
                if (name === "any") {
                    if (this.checked) {
                        mat.clear();
                    }
                    else {
                        return (false);
                    }
                }
                else {
                    if (this.checked) {
                        mat.add(name);
                    }
                    else {
                        mat.remove(name);
                    }
                }
                return (true);
            });
        conf.queryHistory.updateableAdd(that);
        mat.updateableAdd(that);
        if ($.browser.msie) {
            $("div.mat", container).css("display", "block");
        }
        update(that, {hint: "mat"});
    },
    vk_delete = function () {
        container.remove();
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.update = update;
    create();
    return (that);
};


var VKViewQueryAdvanced = function (conf) {
    var that = VKView(conf),
    cats = conf.cats,
    keys,
    query = null,
    matVw,
    container,
    qContainer,
    matContainer,
    packageLength = vkConfHits.packageLength,

    searchInSelectedCats = function () {
        var i, keys = [], vals = [], ops = [], empty = true, date,
        fromDate, toDate, match;
        $("div[name=vkQueryAdvanced] select[name=key] option").each(
            function (i) {
                if ($(this).attr("selected")) {
                    keys.push(this.value);
                }
            });
        $("div[name=vkQueryAdvanced] input[name=value]").each(
            function (i) {
                if (this.id !== 'qx_date') {
                    vals.push(this.value);
                }
            });
        $("div[name=vkQueryAdvanced] select[name=op] option").each(
            function (i) {
                if ($(this).attr("selected")) {
                    ops.push(this.value);
                }
            });
        for (i = 0; i < vals.length; i += 1) {
            if ((vals[i] !== null) && (vals[i] !== "")) {
                empty = false;
                break;
            }
        }
        if (empty) {
            return;
        }
        date = $("input#qx_date").val();
        if ((date !== null) && (date !== "")) {
            match = date.match(/^\s*(\d+)\s*-\s*(\d+)\s*$/);
            if (match) {
                fromDate = match[1];
                toDate = match[2];
                if (fromDate > toDate) {
                    date = toDate + '-' + fromDate;
                }
            }
            keys.push("date");
            vals.push(date);
            ops.push('and');
        }

        query = VKQuery({keys: keys,
                         vals: vals,
                         ops: ops,
                         mats: conf.mat.matsGet(),
                         cats: cats.selectedGet()});
        query = conf.queryHistory.add(query);
        // conf.queryHistory.updateUpdateables({hint: "query-history"});
        cats.search({query: query,
                    first: 1,
                    last: packageLength});
        return (false);
    },

    update = function (src, args) {
        var defKeys, defOp, defVal, hint, i, j, id, key, query, op, val,
        date = null, useDefs;
        /*
        var hint, i, id, key, op, query, oa, oo, on, sel, sa, sf, si, ss, st, 
        soa, soo, son, text;
        */
        hint = args ? (args.hint ? args.hint : "") : "";
        if (hint === 'query-dlg') {
            query = conf.query;
        }
        else if (hint === 'query-history') {
            query = conf.queryHistory.sel();
        }
        else if (hint === 'query-history-select') {
            query = conf.queryHistory.sel();
        }
        else {
            return;
        }
//      if (!query) {
//          return;
//      }
//      sel = 'selected',
        defKeys = [];
        for (i = 0; i < 3; i += 1) {
            defKeys[i] = keys[i][0];
        }
        defVal = "";
        defOp = "and";
        if (query) {
            query = query.get();
        }
        for (i = 0; i < 3; i += 1) {
            id = 'qx2_' + i;
            $("tr#" + id + " select[name=key] option", qContainer).
            removeAttr("selected");
            $("tr#" + id + " select[name=op] option", qContainer).
            removeAttr("selected");
            useDefs = true;
            if (query && query.vals[i]) {
                key = query.keys[i];
                val = query.vals[i];
                if (key === "date") {
                    date = val;
                }
                else {
                    useDefs = false;
                    op = query.ops[i];
                    for (j = 0; j < 3; j += 1) {
                        if (defKeys[j] === key) {
                            defKeys.splice(j, 1);
                            break;
                        }
                    }
                }
            }
            if (useDefs) {
                key = defKeys[0];
                defKeys.splice(0, 1);
                val = defVal;
                op = defOp;
            }
            if (op === null) {
                op = defOp;
            }
            $("tr#" + id + " select[name=key] option[value=" + key +
              "]", qContainer).attr("selected", "selected");
            $("tr#" + id + " :text", qContainer).attr("value", val);
            if (i < 2) {
                if (op === 'and not') {
                    $("tr#" + id + " select[name=op] option:last",
                      qContainer).attr("selected", "selected");
                }
                else {
                    $("tr#" + id + " select[name=op] option[value=" + op +
                      "]", qContainer).attr("selected", "selected");
                }
            }
        }
        if (date !== null) {
            $("input#qx_date").val(date);
        }
    },

    datesEnter = function (event) {
        // only 0..9 or - or Ctrl-Code
        //alert(event.keyCode);
        if ((48 <= event.charCode) && (event.charCode <= 57)) {
        }
        else if (event.charCode === 45) {
        }
        else if (event.charCode === 0) {
        }
        else {
            return false;
        }
        /*
        date = $("input#qx_date").val();
        //alert(date);
        if (date.match(/^\s*$/)) {
            mode = '';
        }
        else if (date.match(/-/)) {
            mode = 'yi';
        }
        else {
            mode = 'y';
        } 
        */
        that.updateUpdateables({hint: 'dates'});
        return true;
    },

    submitEnter = function (event) {
        var form;
        if (event.keyCode === 13) {
            form = $(this).parents().find('form')[0];
            $(form).submit();
            return false;
        }
        else {
            return true;
        }
    },

    create = function () {
        var html, i, id, j;
        keys = [["all", "Überall"],
                ["title", "Titel"],
                ["person", "Person"],
                ["subject", "Schlagwort"],
                ["id", "Nummer"]];
        if (vkConfQueryFields) {
            keys = vkConfQueryFields;
        }
        html = 
        '<div class="vkBox" name="vkQueryAdvanced">' + "\n" + 
         '<table>' + "\n" + 
         '<tr>' + "\n" + 
         '<td>' + "\n" + 
          '<form class="query" action="#">' + "\n" + 
            '<table>';
        for (i = 0; i < 3; i += 1) {
            id = 'qx2_' + i;
            html +=
              '<tr id="' + id + '">' + "\n" + 
                '<td>' + "\n" + 
                  '<select name="key">' + "\n";
            for (j = 0; j < keys.length; j += 1) {
                html +=
                    '<option value="' + keys[j][0] + '">' + 
                        keys[j][1] + 
                    '<\/option>' + "\n";
            }
            html +=
                  '<\/select>' + 
                '<\/td>' + 
                '<td>' + 
                '<input type="text" name="value" value="" size="25" >' + 
                '<\/td>';
            if (i < 2) {
                html +=
                '<td>' +
                  '<select name="op">' + 
                    '<option value="and">und<\/option>' + 
                    '<option value="or">oder<\/option>' + 
                    '<option value="and not">und nicht<\/option>' + 
                  '<\/select>' +
                '<\/td>';
            }
            else { // (i === 2)
                html +=
                '<td style="vertical-align: middle;">' + 
                  '<input type="button" name="search" value="Suchen" ' +
                         'style="font-size: small">' +
		'<\/td>';
            }
        }
        html +=
              '<\/tr>' + 
              '<tr>' + 
                '<td style="vertical-align: middle;">' + 
                  'Jahr' +  '&nbsp;' + 
                  '<a href="jahr-info.html" target="_blank" ' +
	             'onclick="FensterOeffnen(this.href); return false"' +
                     'title="Info zur Sucheinschränkung auf ' +
                           'Erscheinungsjahr(e)">' + 
                    '<img src="images/i.gif" style="border: none;">' + 
                  '<\/a>' + 
                '<\/td>' +  "\n" + 
                '<td>' + 
                  '<input id="qx_date" type="text" name="value" ' +
                         'value="" size="25" >' + 
                '<\/td>' + 
	      '<\/tr>';

        html +=
              '<tr>' + 
                '<td><\/td>' + 
                '<td>' + 
                  '<span style="font-size: xx-small;">' + 
                    '<a href="#">' + 
                      '[Eingabefelder leeren]' + 
                    '<\/a>' + 
                  '<\/span>' + 
                '<\/td>' + 
	      '<\/tr>';

        html +=
            '<\/table>' + 
          '<\/form>' + 
         '<\/td>' + 
        /*
         '<td id="mat" height="100%">' + 
         '<\/td>' + 
         '<\/tr>' + 
        */
         '<\/table>' + 
        '<\/div>';
        container = conf.container;
        qContainer = conf.containerQ;
        matContainer = conf.containerMat;
        qContainer.append($(html));
        // qContainer = $("div.vkBox[name=vkQueryAdvanced]", container);
        /*
        matContainer = $("div.vkBox[name=vkQueryAdvanced] td#mat",
			 conf.container);
        */
        if (vkConfMatViewEnable()) {
            matVw = VKViewMat({container: matContainer, 
                               queryHistory: conf.queryHistory,
                               mat: conf.mat});
        }
        $("div[name=vkQueryAdvanced] a").bind('click', function () {
                $("div[name=vkQueryAdvanced] input[type=text]").
                    attr("value", "");
                return (false);
            });
        $("div[name=vkQueryAdvanced] input[name=search]").
          bind('click', searchInSelectedCats);
        $("div[name=vkQueryAdvanced] form.query").
          bind('submit', searchInSelectedCats);
        $("div[name=vkQueryAdvanced] form.query input:text").
            bind('keypress', submitEnter);
        //$("#qx_date").unbind('keypress', submitEnter);
        $("#qx_date").bind('keyup', datesEnter);
        conf.queryHistory.updateableAdd(that);
        update(that, {hint: "query-dlg"});
        // searchInSelectedCats();
    },
    decode = function (value) {
        return (decodeURIComponent(value));
    },
    vk_delete = function () {
        matVw.vk_delete();
        container.remove();
    },
    hide = function () {
        container.hide();
    },
    queryGet = function () { 
        return (query);
    },
    show = function () {
        container.show();
        $("form.query input:text:first", container).focus();
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.hide = hide;
    that.queryGet = queryGet;
    that.searchInSelectedCats = searchInSelectedCats;
    that.show = show;
    that.update = update;

    create();

    return (that);
};


var VKViewQueryHistory = function (conf) {
    // weil IE6 bei select keine innerHTML-Änderungen unterstützt ...
    var that = VKView(conf),
    cnt,
    selCnt,

    onChange = function (event) {
        var pos = Number(this.value);
        conf.queryHistory.querySelectByPos(pos);
    },

    update = function (src, args) {
        var disable, hint, html, i, isSimpleSearch, q, qs, queries, qref,
        found, select, width;
        hint = args ? (args.hint ? args.hint : "") : "";
        if (hint !== 'query-history') {
            return;
        }
        queries = conf.queryHistory.queriesGet();
        selCnt.empty();
        isSimpleSearch = (conf.menu.selectionGet() === "simpleSearch");
        found = false;
        width = vkConfMatViewEnable() ? '40em' : '25em'; 

        html =
        '<select  name="queryHistory" style="width: ' + width + ';">' + '\n';
        for (i = 0; i < queries.length; i += 1) {
            q = queries[i];
            qs = q.asDisplayStringGet();
            disable = isSimpleSearch ?
                (q.isSimple() ? "" : ' disabled="disabled"') : "";
            if ($.browser.msie) {
                disable = '';
            }
            if (q === args.q) {
                select = ' selected="selected"';
                found = true;
            }
            else {
                select = '';
            }
            html += 
            '<option value="' + i + '"' + disable + select + '>' +
                qs + '<\/option>' + '\n';
        }
        if (!found) {
            html +=
            '<option value="-1" selected="selected">&#160;<\/option>' + 
            '\n';
        }
        html += '<\/select>' + '\n';
        selCnt.replaceWith(html);
        selCnt = $("select", cnt);
        selCnt.bind('change', onChange);
    },

    create = function () {
        var html;
        html = 
        '<div class="vkBox" name="vkQueryHistory">' + "\n" +
          'Suchhistorie:' + "\n" +
          '<select name="queryHistory">' + "\n" +
          '<\/select>' + "\n" +
        '<\/div>';
        conf.container.append($(html));
        cnt = $("div[name=vkQueryHistory]", conf.container);
        selCnt = $("select", cnt);
        conf.queryHistory.updateableAdd(that);
        update(that, {hint: "query-history"});
        selCnt.bind('change', onChange);
        /*
        if ($.browser.msie) {
            cnt.css("display", "none");
        }
        */
    },

    vk_delete = function () {
        conf.queryHistory.updateableRemove(that);
        cnt.remove();
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.update = update;

    create();

    return (that);
};


var VKViewSearchURL = function (conf) {
    var that = VKView(conf),
    cont,
    title = 'Permalink für die aktuelle Suche',

    create = function () {
        var html;
        html = 
        //'<div class="vkBox" id="searchURL">' + '\n' + 
        '<div class="permalink" id="searchURL">' + '\n' + 
        //'Such-URL:' + '\n' + 
          '<a href="" title="' + title + '"></a>' + '\n' + 
        '</div>';
        conf.cont.append($(html));
        cont = $("div#searchURL", $(conf.cont));
        conf.cats.updateableAdd(that);
    },

    vk_delete = function () {
        cont.remove();
    },

    hide = function () {
        cont.hide();
    },

    show = function () {
        cont.show();
    },

    update = function (src, args) {
        //$("a", cont).html('Suche'); 
        //$("a", cont).html('Permalink'); 
        $("a", cont).html('Permalink für die Suche'); 
        //$("a", cont).html(title + ':' + 
        //                  args.query.asDisplayStringGet());
        $("a", cont).attr("href", args.query.asURLGet() + vkStyles.urlPart());
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.hide = hide;
    that.show = show;
    that.update = update;

    create();

    return (that);
};


var VKViewQueryHelp = function (conf) {
    var that = VKView(conf),
    cnt,
    selCnt,
    create = function () {
        var html;
        html = 
        '<div class="vkBox" name="vkQueryHelp">' + "\n" + 
          '<b>Hinweise zur Suche:<\/b>' + "\n" + 
          '<ul>' + "\n" + 
            '<li>' + "\n" + 
              'Groß- und Kleinschreibung wird nicht unterschieden.' + "\n" + 
            '<\/li>' + "\n" + 
            '<li>' + "\n" + 
              'Mehrere Begriffe werden automatisch durch UND verknüpft' + "\n" + 
            '<\/li>' + "\n" + 
            '<li>' + "\n" + 
              'Mit Anführungszeichen wird nach der genauen' + "\n" + 
              'Wortreihenfolge gesucht' + "\n" +
              '(Phrasensuche): z.B. "Deutsche Sprache"' + "\n" +
            '<\/li>' + "\n" + 
            '<li>' + "\n" + 
              'Trunkierungszeichen sind' + "\n" + 
              '"?" (steht für ein Zeichen) und' + "\n" + 
              '"*" (steht für ein und mehrere Zeichen).' + "\n" + 
              'Beispiel: Sowohl "schille?" als auch "schil*" finden' + "\n" + 
              'das Suchwort "Schiller."' + "\n" + 
            '<\/li>' + "\n" + 
          '<\/ul>' + "\n" +
        '<\/div>';
        conf.container.append($(html));
        cnt = $("div[name='vkQueryHelp']", conf.container);
        conf.searcher.updateableAdd(that);
    },
    vk_delete = function () {
        conf.searcher.updateableRemove(that);
        cnt.remove();
    },
    update = function (src, args) {
        vk_delete();
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.update = update;

    create();

    return (that);
};


var VKViewQuery = function (conf) {
    var that = VKView(conf),
    vwA,
    vwH,
    vwHelp,
    vwS,
    mode = conf.mode,
    cnt = null,
    cntSS = null,
    cntAS = null,
    cntASQ = null,
    cntASMat = null,
    cntHist = null,
    cntUrl = null,
    vwSUrl,

    update = function (menu) {
        var newMode = menu.selectionGet(), query;
        // alert('menu selection "'+newMode+'"');
        if (newMode === mode) {
            return;
        }
        mode = newMode;
        if (newMode === "simpleSearch") {
            vwA.hide();
            vwS.show();
            vwH.update(that, {hint: 'query-history', q: vwS.queryGet()});
        }
        else if (newMode === "advancedSearch") {
            vwS.hide();
            vwA.show();
            vwH.update(that, {hint: 'query-history', q: vwA.queryGet()});
        }
    },

    create = function () {
        var html, parent;
        conf.menu.updateableAdd(that);
        html =
        '<div class="vkBox" name="vkQuery">' +
        '  <table>' +
        '    <tr>' +
        '      <td id="qss" colspan="2">' +
        '      <\/td>' +
        '    <\/tr>' +
        '    <tr id="tr-qas">' +
        '      <td id="qas">' +
        '      <\/td>' +
        '      <td id="qmat">' +
        '      <\/td>' +
        '    <\/tr>' +
        '    <tr>' +
        '      <td id="qhist" colspan="2">' +
        '      <\/td>' +
        '    <\/tr>' +
        '    <tr>' +
        '      <td id="qurl" colspan="2">' +
        '      <\/td>' +
        '    <\/tr>' +
        '  <\/table>' +
        //  'Suchanfrage:'+
        '<\/div>';
        conf.container.append($(html));
        cnt = $("div[name=vkQuery]", conf.container);
        cntSS = $("#qss", conf.container);
        cntAS = $("#tr-qas", conf.container);
        cntASQ = $("#qas", conf.container);
        cntASMat = $("#qmat", conf.container);
        cntHist = $("#qhist", conf.container);
        cntUrl = $("#qurl", conf.container);
        vwS = VKViewQuerySimple({cats: conf.cats,
                                 container: cntSS,
                                 mat: conf.mat,
                                 query: conf.query,
                                 queryHistory: conf.queryHistory});
        vwA = VKViewQueryAdvanced({cats: conf.cats,
                                   container: cntAS,
                                   containerQ: cntASQ,
                                   containerMat: cntASMat,
                                   mat: conf.mat,
                                   query: conf.query,
                                   queryHistory: conf.queryHistory});
        vwH = VKViewQueryHistory({container: cntHist,
                                  menu: conf.menu,
                                  queryHistory: conf.queryHistory});
        vwSUrl = VKViewSearchURL({cats: conf.cats, cont: cntUrl});
        if (conf.query === null) {
            vwHelp = VKViewQueryHelp({container: cnt,
                                      query: conf.query,
                                      queryHistory: conf.queryHistory,
                                      searcher: conf.searcher});
        }
        else {
            vwHelp = null;
        }
        update(conf.menu);
    },

    search = function () {
        if (mode === "simpleSearch") {
            vwS.searchInSelectedCats();
        }
        else if (mode === "advancedSearch") {
            vwA.searchInSelectedCats();
        }
    },

    vk_delete = function () {
        vwA.vk_delete();
        if (vwH) {
            vwH.vk_delete();
        }
        vwS.vk_delete();
        conf.menu.updateableRemove(that);
        cnt.remove();
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.search = search;
    that.update = update;

    create(conf.mode);

    that.vwA = vwA;

    return (that);
};


var VKViewCoins = function (conf) {
    var that = VKView(conf),
    container,
    coins = window.vkCoins,

    create = function () {
        var html =
        //'<div class="coins">'+conf.coins+'<\/div>';
        '<div class="coins"><\/div>';
        conf.container.append($(html));
        container = $("div.coins", conf.container);
        coins.updateableAdd(that);
        coins.add(conf.coins, that);
    },

    vk_delete = function () {
        coins.remove(conf.coins, that);
        coins.updateableRemove(that);
        container.remove();
    },

    update = function (basket, args) {
        if (args.hint === 'active') {
            container.empty();
            container.html(conf.coins);
            $("div.coins.seed").remove();
        }
        else if (args.hint === 'inactive') {
            container.empty();
        }
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.update = update;

    create();

    return (that);
};


var VKViewCatHit = function (conf) {
    var that = VKView(conf),
    container,
    coinsVw = null,
    hit = conf.hit,
    isbn = null, issn = null,
    label,
    no = conf.no,
    pos = conf.pos,
    num,
    hasBestand = false,
    intoBasketTitle = "In die Merkliste übertragen",
    outofBasketTitle = "Aus der Merkliste entfernen",
    intoBasketOnServer = function () {
        var params, sid, url;
        url = "searcher/intoBasket";
        sid = VKSid();
        params = {sid: sid, hit: conf.cat.id + '_' + catIdiEncode(hit.idi)};
        $.ajax({url: url,
                type: 'POST',
                dataType: 'text',
                data: params,
                success: function () {},
                error: function (xhr, status, exception) {}
            }); 
    },
    outofBasketOnServer = function () {
        var params, sid, url;
        url = "searcher/outofBasket";
        sid = VKSid();
        params = {sid: sid, hit: conf.cat.id + '_' + catIdiEncode(hit.idi)};
        $.ajax({url: url,
                type: 'POST',
                dataType: 'text',
                data: params,
                success: function () {},
                error: function (xhr, status, exception) {}
            }); 
    },
    intoBasket = function () {
        conf.basket.hitAdd(conf.cat, hit);
        intoBasketOnServer();
        this.title = outofBasketTitle;
        return (true);
    },
    outofBasket = function () {
        conf.basket.hitRemove(conf.cat, hit);
        outofBasketOnServer();
        this.title = intoBasketTitle;
        return (true);
    },
    bestandReq = function (cat) {
        var data;
        $('div.bestand.' + cat + ' span.wait', container).
        html('<img src="images/waits.gif">');
        data = { c: cat,
                 n: num };
        $.ajax({url: "searcher/bestand.html",
                type: 'GET',
                dataType: 'html',
                data: data,
                success: function (html) {
                    // alert("success cat "+cat);
                    if (html.match(/^\s*$/)) {
                        html = '<span>Nichts gefunden.<\/span>';
                    }
                    $('div.bestand.' + cat + ' span.wait', container).empty();
                    $("div.bestand." + cat, container).append(html);
                },
                error: function (xhr, status, exception) {
                    // alert('cat-'+cat+' error: "'+status+'"');
                    $('div.bestand span.wait', container).text("E");
                }}); 
    },
    bestand = function () {
        var html,
        un = {
            bvb: "Bibliotheksverbund Bayern",
            gbv: "Gemeinsamer Bibliotheksverbund der Länder Bremen, Hamburg, Mecklenburg-Vorpommern, Niedersachsen, Sachsen-Anhalt, Schleswig-Holstein, Thüringen und der Stiftung Preußischer Kulturbesitz",
            hbz: "Hochschulbibliothekszentrum des Landes Nordrhein-Westfalen",
            hebis: "Hessisches Bibliotheks- und Informationssystem",
            kobv: "Kooperativer Bibliotheksverbund Berlin-Brandenburg",
            swb: "Südwestdeutscher Bibliotheksverbund"
        },
        arrowUp = function (id) {
            return ('<a href="#' + id + '" title="Zum Trefferanfang">' + 
                    '  <img src="images/arrow-up.png" align="right" ' + 
                    '       style="border: 0pt; padding: 0pt 5px;">' +
                    '<\/a>');
        };
        if (hasBestand) {
            $("div.bestandBox", container).remove();
            hasBestand = false;
            return (false);
        }
        html =
        '<div class="bestandBox">' + "\n" + 
          '<a class="close" href="#">' + 
            '<img src="images/zu.gif" alt="Schliessen" ' + 
                 'align="right" border="0" ' + 
                 'title="Nachweisinformationen Schliessen">' + 
          '<\/a>' + 

	//'<b>' + mt('Nachweisinformationen') + ':<\/b>' + "\n" + 
        
	'<b>' + 'Nachweisinformationen' + ':<\/b>' + "\n" + 
          '<div class="bestand bvb">' + "\n" + 
            '<div class="verbund" title="' + un.bvb + '">' + "\n" + 
              '<a href="http://gateway-bayern.bib-bvb.de/" ' + 
                 //'class="externalLink"' + "\n" +
                 'target="_blank">' + "\n" + 
                '<b>' + un.bvb + '<\/b>' + "\n" + 
              '<\/a>' + "\n" + 
              '<span class="wait"><\/span>' + "\n" + 
              arrowUp(label) +        
            '<\/div>' + "\n" + 
          '<\/div>' + "\n" + 
          '<div class="bestand gbv">' + "\n" + 
            '<div class="verbund" title="' + un.gbv + '">' + "\n" + 
              '<a href="http://gso.gbv.de/xslt/DB=2.1/" ' + 
                 //'class="externalLink"' + "\n" +
                 'target="_blank">' + "\n" + 
                '<b>' + un.gbv + '<\/b>' + "\n" + 
              '<\/a>' + "\n" + 
              '<span class="wait"><\/span>' + "\n" + 
              arrowUp(label) +        
            '<\/div>' + "\n" + 
          '<\/div>' + "\n" + 
          '<div class="bestand hbz">' + "\n" + 
            '<div class="verbund" title="' + un.hbz + '">' + 
             "\n" + 
              '<a href="http://okeanos-www.hbz-nrw.de/F/" ' + 
                 //'class="externalLink"' + "\n" +
                 'target="_blank">' + "\n" + 
                '<b>' + un.hbz + '<\/b>' + "\n" + 
              '<\/a>' + "\n" + 
              '<span class="wait"><\/span>' + "\n" + 
              arrowUp(label) +        
            '<\/div>' + "\n" + 
          '<\/div>' + "\n" + 
          '<div class="bestand hebis">' + "\n" + 
            '<div class="verbund" title="' + un.hebis + '">' + "\n" + 
              '<a href="http://cbsopac.rz.uni-frankfurt.de/LNG=DU&CHARSET=UTF-8/DB=2.1/" ' + 
                 //'class="externalLink"' + "\n" +
                 'target="_blank">' + "\n" + 
                '<b>' + un.hebis + '<\/b>' + "\n" + 
              '<\/a>' + "\n" + 
              arrowUp(label) +        
              '<span class="wait"><\/span>' + "\n" + 
            '<\/div>' + "\n" + 
          '<\/div>' + "\n" + 
          '<div class="bestand kobv">' + "\n" + 
            '<div class="verbund" title="' + un.kobv + '">' + "\n" + 
              '<a href="http://digibib.kobv.de/" ' + 
                 //'class="externalLink"' + "\n" +
                 'target="_blank">' + "\n" + 
                '<b>' + un.kobv  + '<\/b>' + "\n" + 
              '<\/a>' + "\n" + 
              arrowUp(label) +        
              '<span class="wait"><\/span>' + "\n" + 
            '<\/div>' + "\n" + 
          '<\/div>' + "\n" + 
          '<div class="bestand swb">' + "\n" + 
            '<div class="verbund" title="' + un.swb + '">' + "\n" + 
              '<a href="http://swb.bsz-bw.de/" ' + 
                 //'class="externalLink"' + "\n" +
                 'target="_blank">' + "\n" + 
                '<b>' + un.swb + '<\/b>' + "\n" + 
              '<\/a>' + "\n" + 
              arrowUp(label) +        
              '<span class="wait"><\/span>' + "\n" + 
            '<\/div>' + "\n" + 
          '<\/div>' + "\n" + 
          '<a class="close" href="#">' + 
            '<img src="images/zu.gif" alt="Schliessen" ' + 
                 'align="right" border="0" ' + 
                 'title="Nachweisinformationen Schliessen">' + 
          '<\/a>' + 
          '<div class="dummy">&nbsp;<\/div>' + "\n" +
        '<\/div>' + "\n";


        $("div.links", container).before($(html));
        $('div a.close', container).bind("click", bestand);
        hasBestand = true;
        bestandReq("bvb");
        bestandReq("gbv");
        bestandReq("hbz");
        bestandReq("hebis");
        bestandReq("kobv");
        bestandReq("swb");
        return (false);
    },
    iconFromForm = function (form) {
        //  var icon = ['?', 'help.png'];
        var icon = 'unknown.png', f;

        if (form === 'book') {
            icon = ['Bücher', 'book.png'];
            return (icon);
        }
        else if (form === 'journal') {
            icon = ['Zeitschriften/Serien', 'periodical.png'];
            return (icon);
        }
        else if (form === 'periodical') {
            icon = ['Zeitschriften/Serien', 'periodical.png'];
            return (icon);
        }
        else if (form === 'article') {
            icon = ['Aufsätze', 'article.png'];
            return (icon);
        }
        else if (form === 'online-journal') {
            icon = ['Online-Zeitschriften', 'olper.png'];
            return (icon);
        }
        else if (form === 'online-periodical') {
            icon = ['Online-Zeitschriften', 'olper.png'];
            //  icon = ['Online-Publikationen', 'binary.png'];
            return (icon);
        }
        else if (form === 'online-book') {
            icon = ['Online-Publikationen', 'binary.png'];
            return (icon);
        }
        else if (form === 'online-article') {
            icon = ['Aufsätze', 'article.png'];
            return (icon);
        }

        else if (form === 'audio') {
            icon = ['Tonträger', 'sound.png'];
            return (icon);
        }
        else if (form === 'audiovisual') {
            icon = ['Filme, Videos, u.a.', 'audiovisual.png'];
            return (icon);
        }
        else if (form === 'boardgame') {
            icon = ['Spiele', 'object.png'];
            return (icon);
        }
        else if (form === 'bookcd') {
            icon = ['Bücher', 'book.png'];
            // icon = ['CD-Roms, Disketten, u.a.', 'software.png'];
            return (icon);
        }
        else if (form === 'cdrom') {
            icon = ['CD-Roms, Disketten, u.a.', 'software.png'];
            return (icon);
        }
        else if (form === 'hierarchy') {
            icon = ['Mehrbändiges Werk', 'hierarchy.png'];
            return (icon);
        }
        else if (form === 'micro') {
            icon = ['Mikroformen', 'microfilm.png'];
            return (icon);
        }
        else if (form === 'notes') {
            icon = ['Noten', 'score.png'];
            return (icon);
        }
        else if (form === 'online-document') {
            icon = ['Online-Publikationen', 'binary.png'];
            return (icon);
        }
        else if (form === 'katalogkarte') {
            icon = ['Katalogkarte', 'katalogkarte.png'];
            return (icon);
        }

        f = form.substring(0, 2);

        if (f === 'Aa') {
            icon = ['Bücher', 'book.png'];
        }
        else if (f === 'Ac') {
            //  c: Gesamttitelaufnahme eines mehrbändigen begrenzten Werkes
            icon = ['Bücher', 'book.png'];
        }
        else if (f === 'Ab') {
            icon = ['Zeitschriften/Serien', 'periodical.png'];
        }
        else if (f === 'Af') {
            icon = ['Bücher', 'book.png'];
        }
        else if (f === 'Ao') {
            icon = ['Aufsätze', 'article.png'];
        }
        else if (f === 'Ba') {
            icon = ['Filme, Videos, u.a.', 'audiovisual.png'];
        }
        else if (f === 'Ea') {
            icon = ['Mikroformen', 'microfilm.png'];
        }
        else if (f === 'Ga') {
            icon = ['Tonträger', 'sound.png'];
        }
        else if (f === 'Ma') {
            icon = ['Noten', 'score.png'];
        }
        else if (f === 'Oa') {
            icon = ['Online-Publikationen', 'binary.png'];
        }
        else if (f === 'Ob') {
            icon = ['Online-Zeitschriften', 'olper.png'];
        }
        else if (f === 'Oo') {
            icon = ['Aufsätze', 'article.png'];
        }
        else if (f === 'Sa') {
            icon = ['CD-Roms, Disketten u.a.', 'software.png'];
        }
        else if (f === 'Sd') {
            icon = ['CD-Roms, Disketten u.a.', 'software.png'];
        }
        else if (f === 'Sf') {
            icon = ['CD-Roms, Disketten u.a.', 'software.png'];
        }
        else if (f === 'SF') {
            icon = ['CD-Roms, Disketten u.a.', 'software.png'];
        }
/*
        else if (f === '') {
            icon = ['Lokale Katalogisate (Bücher, CD-ROM, ...)', 'icon_misc.png'];
        }
        else if (f === '') {
            icon = ['Kartenmaterial', 'map.png'];
        }
        else if (f === '') {
            icon = ['Handschriften', 'handwriting.png'];
        }
        else if (f === '') {
            icon = ['Illustrationen (Bilder, Dias usw.)', 'picture.png'];
        }
        else if (f === '') {
            icon = ['Anderes Material', 'object.png'];
        }
*/
        else if (f === 'ww') {
            icon = ['Internetquelle', 'www.png'];
        }

        return (icon);
    },
    searchInCats = function (key, val, cats) {
        var i, packageLength, query;
        if (cats === null) {
            cats = conf.cats.selectedGet();
        }
        packageLength = vkConfHits.packageLength;
        query = VKQuery({keys: [key],
                         vals: [val],
                         ops: [],
                         mats: [],
                         cats: cats});
        query = conf.queryHistory.add(query);
        // conf.queryHistory.updateUpdateables({hint: "query-history"});
        conf.cats.search({query: query,
                    first: 1,
                    last: packageLength});
    },
    search = function () {
        var attr, args, classes, field, fields, i, index, val, cats;
        cats = null;
        classes = $(this).parent().parent().attr("class").split(" ");
        field = classes[1];
        index = classes[2];
        if (hit.fields) {
            fields = hit.fields;
        }
        else {
            fields = conf.cat.hitFields();
        }
        for (i = 0; i < fields.length; i += 1) {
            if (fields[i][0] === field) {
                args = fields[i][2];
                attr = args.searchAttr;
                if (args.internal) {
                    cats = [conf.cat];
                }
                break;
            }
        }
        // val = '"'+$(this).text()+'"';

        if (index) {
            val = hit[field][index];
        }
        else {
            val = hit[field];
        }

        if (args.splitAt) {
            val = $(this).html();
            // alert(val);
        }

        if (args.pVal) {
            val = val.match(args.pVal)[1];
        }

        if (args.pRm) {
            val = val.replace(new RegExp(args.pRm, "g"), "");
        }

        searchInCats(attr, val, cats);
        return (false);
    },
    create = function () {
        var alt, args, coins, viewClass = 'long', checked,
        fields, hasSearchLink = false,
        html, html_links, i, icon, img = "book.png", index, j, k, key, name,
        mat = hit.mat,
        mat_title = 'Buch', text,
        title = hit.title || hit.description || '[Kein Titel]',
        // description als Titelersatz für Zettelkatalog
        subtitle = hit.subtitle, basket_title,
        url, url2, openURL = null, opacUrl,
        val, val2, vals, vals2,
        prevName, sel, type, opacUrlClass, first;

        label = hit.cat_id + '-' + hit.id; 

        if (hit.form) {
            icon = iconFromForm(hit.form);
            if (icon) {
                mat_title = icon[0];
                img = icon[1];
            }
        }
        if (subtitle) {
            title += (' : ' + subtitle);
        }
        if (conf.cat.conf.noDetails) {
            title = '<span class="t">' + title + '<\/span>';
        }
        else {
            title = '<span class="t">' + title + '<\/span>';
            title =
            '<a href="#" class="t" title="Details anzeigen">' + 
            title + '&nbsp;' + 
            '[Details]' + 
            '<\/a>';
            viewClass = 'short';
        }
        html =
        '<div class="vkBox" name=' + pos + '>' + "\n" + 
        '<a name="' + label + '">' + "\n" + 
        '<\/a>' + "\n" + 
        // hit begin:
        '<div class="hit ' + viewClass + '">' + "\n";

        html +=
          '<table width="100%">' + "\n" +
          '<tr>' + "\n" +
	  '<td class="merkliste" align="center">' + "\n";

        if (conf.basketCnt || conf.basket.isHitInBasket(conf.cat, hit)) {
            checked = ' checked="checked"';
        }
        else {
            checked = '';
        }

        basket_title = (checked === '') ? intoBasketTitle : outofBasketTitle;
        basket_title = 'title="' + basket_title + '"';

        html += 
        '<span style="font-size: xx-small;">Merkliste<\/span>&nbsp;<br>';

        html += 
        '<input type="checkbox"' + checked + basket_title + '>&nbsp;' + "\n";

        html +=
	  '<\/td>' + "\n" +
	  '<td width="100%">' + "\n";

        html +=
          '<div class="head">' + "\n";
        if (icon) {
            html +=
                  '<img src="images/mat/' + img + '" title="' + mat_title + '">';
        }
        html +=
        '<span class="no">' + no +  '.<\/span>' + '&nbsp;' + title + "\n";
        html +=
        '<\/div>'; // head

        html +=
        '<div class="body">' + 
              '<div>';

        if (hit.fields) {
            fields = hit.fields;
        }
        else {
            fields = conf.cat.hitFields();
        }
        for (i = 0; i < fields.length; i += 1) {
            key = fields[i][0];
            name = fields[i][1];
            if (key === "title") {
                continue;
            }
            else if (key === "alt") {
                continue;
            }
            else if (key === "karte_url") {
                continue;
            }
            vals = hit[key];
            if (vals) {
                type = typeof(vals);
                if (type !== "object") {
                    vals = [vals];
                }
                for (k = 0; k < vals.length; k += 1) {
                    val = vals[k];
                    args = fields[i][2];
                    if (args) {
                        if (args.isExtLink) {
                            if (!conf.basketCnt) {
                                //text = (args.name) ? args.name : val;
                                if (args.name) {
                                    text = args.name;
                                }
                                else {
                                    text = val;
                                    if (text.length > 70) {
                                        text = text.substring(0, 70) + '...';
                                    }
                                }
                                val = '<a class="externerLink" href="' + val +
                                    '" target="_blank">' + text + '<\/a>';
                            }
                        }
                        else if (args.isSearchLink) {
                            if (args.splitAt === null) {
                                vals2 = [val];
                            }
                            else {
                                vals2 = val.split(args.splitAt);
                            }
                            val = "";
                            for (j = 0; j < vals2.length; j += 1) {
                                if (val !== "") {
                                    val += "; ";
                                }
                                val2 = vals2[j];
                                if (args.pName) {
                                    val2 = val2.match(args.pName)[1];
                                }
                                if (conf.basketCnt) {
                                    val += val2;
                                }
                                else {
                                    val +=
                                        '<a class="searchLink" href="#">' +
                                          val2 +
                                        '<\/a>';
                                    hasSearchLink = true;
                                }
                            }
                        }
                    }
                    if (k > 0) {
                        name = "";
                    }
                    else {
                        name += ":";
                    }
                    index = (type === "object") ? " " + k : "";
                    html +=
                    '<div class="field ' + key + index + '">' + "\n" + 
                      '<div class="key">' + name + '<\/div>' + "\n" + 
                      '<div class="val">' + val + '<\/div>' + "\n" + 
                    '<\/div>' + "\n";
                }
            }
        }

        if (hit.iasl_id) {
            html +=
            '<div class="field rez">' + "\n" + 
              '<div class="key">Rezension:<\/div>' + "\n" + 
              '<div class="val">' + "\n" + 
                '<a href="' + vkConfIASLURLs.rezURL + hit.iasl_id + '" ' + 
                   'target="_blank">' + "\n" + 
                   'IASLonline' + "\n" + 
                '<\/a>' + "\n" + 
              '<\/div>' + "\n" + 
            '<\/div>' + "\n";
        }

        html +=
              '<\/div>' + 
              '<\/div>'; // body
    
        val = hit.karte_url;
        if (val) {
            html +=
                '<div class="karte"><\/div>' + "\n";
        }

        if (conf.basketCnt) {
            html +=
                '<div class="cat">' + "\n" + 
                  '<i>' + conf.cat.nameGet() + '<\/i>' +
                '<\/div>' + "\n";
        }

        if (conf.basketCnt) {
            html +=
            '<div class="rem">' + "\n" + 
              '<span class="name">' + 'KOMMENTAR' + ':' + '<\/span>' +
              '<input type="text" size="30" value="">' + "\n" + 
              '<span class="rem"><\/span>' + "\n" + 
            '<\/div>' + "\n";
        }

        html_links = '';

        opacUrl = opacUrlGet(hit);
        url = opacUrl.opac_url;
        if (url && (url.substring(0, 1) === "/")) {
            url = "http://" + window.location.hostname + url;
        }
        url2 = opacUrl.opac_url_natde;
        if (url2 && (url2.substring(0, 1) === "/")) {
            url2 = "http://" + window.location.hostname + url2;
        }
        if (url && url2) { // zur Zeit nur bei Nationsllizenzen
            // single line for link buttons
            opacUrlClass = vkStyles.hasStyle('slflb') ? '' :
            ' class="ownLine"';
            html_links +=
            '<div' + opacUrlClass + '>' + 
	    '<div>' +
            '<a href="nat-urls-info.html" target="_blank" ' +
	       'onclick="FensterOeffnen(this.href); return false"' +
               'title="Info zu den beiden OPAC-Knöpfen">' + 
              '<img src="images/i.gif">' + 
            '<\/a>' + 
	    '<\/div>' +
            '&nbsp;' + 
	    '<div class="opac">' +
            '<a href="' + url + '" target="_blank" ' +
               'title="Zum Katalog">' + 
              '<img src="images/links/opac-nl.png">' + 
            '<\/a>' + 
	    '<\/div>' +
	    '<div>' +
            ' / ' + 
	    '<\/div>' +
	    '<div class="opac">' +
            '<a href="' + url2 + '" target="_blank" ' +
               'title="Nationallizenzen.de-URL für Privatnutzer">' + 
              '<img src="images/links/opac-nl-privatpersonen.png">' + 
            '<\/a>' + 
	    '<\/div>' +
	    '<\/div>';
        }
        else if (url) {
            opacUrlClass = vkStyles.hasStyle('slflb') ? ' class="opac"' :
            ' class="opac ownLine"';
            if (conf.cat.conf.windowOpen) {
                html_links +=
        '<div' + opacUrlClass + '>' + 
            '<a onclick="' + conf.cat.conf.windowOpen + '(this.href); ' +
                         'return false"' + 
            '   href="' + url + '" target="_blank" title="Zum Katalog">' + 
              '<img src="images/links/opac.png">' + 
            '<\/a>' + 
        '<\/div>';
            }
            else {
                html_links +=
        '<div' + opacUrlClass + '>' + 
            '<a href="' + url + '" target="_blank" title="Zum Katalog">' + 
              '<img src="images/links/opac.png">' + 
            '<\/a>' + 
        '<\/div>';
            }
        }
        if ((html_links !== '') && vkStyles.hasStyle('slflb')) {
            html_links += '&nbsp;&nbsp;';
        }

        isbn = (hit.isbn && typeof(hit.isbn) === "object") ? hit.isbn[0] :
            hit.isbn;
        num = isbn;
        /*
        if (!num) {
            issn = (hit.issn && typeof(hit.issn) === "object") ? hit.issn[0] :
                hit.issn;
            num = issn;
        }
        */
        if (num) {
            html_links +=
        '<div>' + 
            '<a class="bestand" href="#" ' + 
                'title="Deutschlandweite Suche">' + 
              '<img src="images/links/union_de.png" ' +
		   'alt="Deutschlandweite Suche">' + 
            '<\/a>' + 
        '<\/div>';
        }
        /*
        if (num) {
            openURL = 'http://www.openurl.de/?';
            if (isbn) {
                openURL += 'isbn=' + isbn;
            }
            if (openURL) {
                html_links += '&nbsp;' + 
        '<div class="openURL">' + 
            '<a href="' + openURL + '" ' + 
               'title="openURL" target="_blank">' + 
              '<img src="images/openurl.gif" alt="openURL">' + 
            '<\/a>' + 
        '<\/div>';
            }
        }
        */
	/*
        if (hit.ezb_link) {
            html_links += '&nbsp;' + 
        '<div>' + 
            '<a class="ezb" ' + 
                'href="' + vkConfEZBURLs.openURL + hit.ezb_link + '" ' + 
                'target="_blank" ' + 
                'title="' + vkConfEZBURLs.title + '">' + 
              '<img src="' + vkConfEZBURLs.img + hit.ezb_link + '" ' + 
                   'alt="' + vkConfEZBURLs.title + '">' + 
            '<\/a>' + 
        '<\/div>';
        }
        if (hit.subito_link) {
            html_links += '&nbsp;' + 
        '<div>' + 
            '<a class="subito" ' + 
                'href="' + vkConfSUBITOURLs.openURL + hit.subito_link + '" ' + 
                'target="_blank" ' + 
                'title="' + vkConfSUBITOURLs.title + '">' + 
              '<img src="' + vkConfSUBITOURLs.img + '" ' + 
                   'alt="' + vkConfSUBITOURLs.title + '">' + 
            '<\/a>' + 
        '<\/div>';
        }
        if (hit.zdb_id) {
            html_links += '&nbsp;' + 
        '<div>' + 
            '<a class="zdb" ' + 
                'href="' + vkConfZDBURLs.url + hit.zdb_id + '" ' + 
                'target="_blank" ' + 
                'title="' + vkConfZDBURLs.title + '">' + 
              '<img src="' + vkConfZDBURLs.img + '" ' + 
                   'alt="' + vkConfZDBURLs.title + '">' + 
            '<\/a>' + 
        '<\/div>';
        }
	*/

	/**/
        first = true;
        if (hit.ezToLink) {
            for (i = 0; i < vkConfEzToLink.ids.length; i += 1) {
                key = vkConfEzToLink.ids[i];
                val = hit.ezToLink[key];
                if (val) {
                    if (key === 'ezb') {
                        val2 = hit.ezbAmpel;
                        if (!val2) {
                            continue;
                        }
                    }
                    else {
                        val2 = vkConfEzToLink[key].img;
                    }
                    if (num || (!first)) {
                        html_links += '<span>&nbsp;<\/span>';
                    }
                    html_links +=
                        '<div>' + 
                        '<a class="' + key + '" ' + 
                        'href="' + val + '" ' + 
                        'target="_blank" ' + 
                        'title="' + vkConfEzToLink[key].title + '">' + 
                        '<img src="' + val2 + '" ' + 
                        'alt="' + vkConfEzToLink[key].title + 
                        '">' + 
                        '<\/a>' + 
                        '<\/div>';
                    first = false;
                }
            }
        }
	/**/

        if (html_links !== '') {
            html += 
          '<div class="links">' + "\n" + 
            html_links + 
          '<\/div>';
        }

        html +=
	'<\/td>' + "\n" +
	'<\/tr>' + "\n" +
	'<\/table>' + "\n";

        html +=
	'<\/div>' + "\n";
        // hit end

        html +=
          '<\/div>' + "\n";

        if (pos === 0) {
            conf.container.prepend($(html));
        }
        else {
            prevName = pos - 1;
            $("div[name=" + prevName + "]", conf.container).after($(html));
        }
        container = $("div[name=" + pos + "]", conf.container);
        if (!conf.cat.conf.noDetails) {
            $("a.t", container).bind('click', function () {
                    var hitCont, img, title, html, width, height;
                    hitCont = $("div.hit", container);
                    img = $("div.hit img.t", container);
                    title = $("div.hit div.head a.t", container);
                    // 1968px × 1185px
                    if (hitCont.hasClass("short")) {
                        hitCont.removeClass("short");
                        hitCont.addClass("long");
                        title.attr("title", "Details verbergen");
                        if (hit.karte_url) {
                            width = $("div.karte", container).width() - 4;
                            height = Math.floor((width * 1185) / 1968);
                            html = '<img class="karte" src="' + hit.karte_url + 
                                '" width="' + width + '" height="' + height +
                                '">' + "\n";
                            $("div.karte", container).html(html);
                        }
                    }
                    else {
                        hitCont.removeClass("long");
                        hitCont.addClass("short");
                        img.attr("src", "images/open.gif");
                        title.attr("title", "Details anzeigen");
                        if (hit.karte_url) {
                            $("div.karte", container).empty();
                        }
                    }
                    return (false);
                });
        }
        alt = conf.cat.hitShortAlt();
        if (alt) {
            sel = "div.field." + alt;
            $(sel, container).addClass("alt");
        }
        if (hasSearchLink) {
            $("a.searchLink", container).bind('click', search);
        }
        if (num) {
            $("a.bestand", container).bind('click', bestand);
        }
        if (conf.basketCnt || conf.basket.isHitInBasket(conf.cat, hit)) {
            $("input[type=checkbox]", container).bind('click', outofBasket);
        }
        else {
            $("input[type=checkbox]", container).bind('click', intoBasket);
        }
        if (conf.basketCnt) {
            // Basket View will handle update
        }
        else {
            conf.basket.updateableAdd(that);
        }

	/* !!!
        coins = hit.coins;
        if (coins !== null) {
            coinsVw = VKViewCoins({coins: coins, container: container});
        }
	*/
    },
    vk_delete = function () {
        if (!conf.basketCnt) {
            conf.basket.updateableRemove(that);
        }
        if (coinsVw !== null) {
            coinsVw.vk_delete();
            coinsVw = null;
        }
        container.remove();
    },
    update = function (src, args) {
        // alert('VKViewCatHit update hint: "' + args.hint + '"');
        if (args.hint === 'basket-add') {
            if (!((args.hit[0] === conf.cat) && (args.hit[1].idi === hit.idi))) {
                return;
            }
            $("input[type=checkbox]", container).attr('checked', 'checked');
            $("input[type=checkbox]", container).unbind('click', intoBasket);
            $("input[type=checkbox]", container).bind('click', outofBasket);
        }
        else if (args.hint === 'basket-remove') {
            if (!((args.hit[0] === conf.cat) && (args.hit[1].idi === hit.idi))) {
                return;
            }
            $("input[type=checkbox]", container).removeAttr('checked');
            $("input[type=checkbox]", container).unbind('click', outofBasket);
            $("input[type=checkbox]", container).bind('click', intoBasket);
        }
        else if (args.hint === 'basket-clear') {
            $("input[type=checkbox]", container).removeAttr('checked');
            $("input[type=checkbox]", container).unbind('click', outofBasket);
            $("input[type=checkbox]", container).bind('click', intoBasket);
        }
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.update = update;

    create();

    return (that);
};


var VKViewCatHits = function (conf) {
    var that = VKView(conf),
    cat = conf.cat,
    name,
    hitsContainer,
    head2Container,
    footContainer,
    txts,
    vws = [],
    zumAnfang,

    catGet = function () {
        return (cat);
    },

    hitsRemove = function () {
        var vw = null;
        while (true) {
            vw = vws.shift();
            if ((vw === undefined) || (vw === null)) {
                break;
            }
            vw.vk_delete();
        }
    },

    queryShow = function (cat, query) {
        var all, all_enc, link, url;
        // Zur Zeit gibt es nur einen externen Katalog: vkf
        if (query.isSimple()) {
            all = query.get().vals[0];
            all_enc = encodeURIComponent(all);
            url = "http://se3.kobv.de/V?" +
                "portal=KOBV&institute=KOBV&" +
                "func=quick-1-check1&mode=simple&" +
                "find_request_1=" + all_enc + "&group_number=000026952";
            link = '<a href="javascript:wings_gsc=' +
                'wings_vkf=window.open(\'' + url + 
                '\',\'vkf\');wings_vkf.focus();">' +
                'Suchergebnisse werden extern im VK-Film angezeigt<\/a>' +
                '&nbsp;<img border="0" ' +
                'src="lib/images/link-extern-rot-2.gif" ' +
                'title="In eigenem Fenster"/>\n';
            /*
              member_id = 'hC_'+cat.id;
              link_tr = '<tr class="'+member_id+'"><td>'+
              '<\/td><td>'+link+'<\/td><\/tr>';
            */
            hitsContainer.html(link);
        }
        else {
            hitsContainer.html('Die erweiterte Suche wird zur Zeit ' +
                               'für diesen Katalog noch nicht unterstützt.');
        }
    },

    navShow = function (hits, cat, first, last, packageLength, totalLength,
                        container) {
        if (totalLength > 0) {
            if ((hits.totalLength !== null) &&
                (parseFloat(hits.totalLength) > parseFloat(totalLength))) {
                container.text("Treffer " + first + " - " + last +
                               " von " + totalLength +
                               ' (insgesamt ' + hits.totalLength + ')');
            }
            else {
                container.text("Treffer " + first + " - " + last +
                               " von insgesamt " + 
                               totalLength);
            }
        }
        else {
            container.text("Keine Treffer");
        }
        if (first > packageLength) {
            container.append($('<div class="nav">' + 
                                   '<button class="begin" ' + 
                                   'title="' + 'Anfang der Trefferliste' + '">' + 
                                   '<img src="images/arrow-begin.png">' + 
                                   '<\/button>' + 
                                   '<\/div>'));
            $(".begin", container).bind('click', function () {
                    var f = 1, l;
                    l = f + packageLength - 1;
                    if (l > totalLength) {
                        l = totalLength;
                    }
                    cat.search({query: null,
                                first: f,
                                last: l});
                    location.href = '#' + 'vkCatHits-' + cat.id;
                    return (false);
                });
        }
        if (first > 1) {
            container.append($('<div class="nav">' + 
                                   '<button class="backwards" ' + 
                                   'title="' + 'Vorherige Treffer' + '">' + 
                                   '<img src="images/arrow-left.png">' + 
                                   '<\/button>' + 
                                   '<\/div>'));
            $(".backwards", container).bind('click', function () {
                    var f = first - packageLength, l;
                    if (f < 1) {
                        f = 1;
                    }
                    l = f + packageLength - 1;
                    if (l > totalLength) {
                        l = totalLength;
                    }
                    cat.search({query: null,
                                first: f,
                                last: l});
                    location.href = '#' + 'vkCatHits-' + cat.id;
                    return (false);
                });
        }
        if (first + packageLength - 1 < totalLength) {
            container.append($('<div class="nav">' + 
                                   '<button class="forwards" ' + 
                                   'title="' + 'Weitere Treffer' + '">' + 
                                   '<img src="images/arrow-right.png">' + 
                                   '<\/button>' + 
                                   '<\/div>'));
            $(".forwards", container).bind('click', function () {
                    var f = first + packageLength, l = f + packageLength - 1;
                    if (l > totalLength) {
                        l = totalLength;
                    }
                    cat.search({query: null,
                                first: f,
                                last: l});
                    location.href = "#" + 'vkCatHits-' + cat.id;
                    return (false);
                });
        }
        if (first + 2 * packageLength - 1 < totalLength) {
            container.append($('<div class="nav">' + 
                                   '<button class="end" ' + 
                                   'title="' + 'Ende der Trefferliste' + '">' + 
                                   '<img src="images/arrow-end.png">' + 
                                   '<\/button>' + 
                                   '<\/div>'));
            $(".end", container).bind('click', function () {
                    var f = Math.floor((totalLength - 1) / packageLength) *
                        packageLength + 1,
                        l = totalLength;
                    cat.search({query: null,
                                first: f,
                                last: l});
                    location.href = "#" + 'vkCatHits-' + cat.id;
                    return (false);
                });
        }
        container.append($('<div class="wait"><\/div>'));
    },

    hitsShow = function (cat) {
        var hits, first, last, totalLength, length, i, html, vw, packageLength;
        packageLength = vkConfHits.packageLength;
        hits = cat.hitsGet();
        if (!hits) {
            return;
        }
        first = hits.first + 1;
        totalLength = hits.length;
        length = (hits && hits.hits) ? hits.hits.length : 0;
        last = first + length - 1;
        hitsRemove();
        head2Container.empty();
        footContainer.empty();
        for (i = 0; i < length; i += 1) {
            vw = VKViewCatHit({basket: conf.basket,
                               basketCnt: false,
                               cat: cat,
                               cats: conf.cats,
                               container: hitsContainer,
                               hit: hits.hits[i],
                               lang: conf.lang,
                               no: first + i,
                               pos: i,
                               queryHistory: conf.queryHistory});
            vws.push(vw);
        }
        navShow(hits, cat, first, last, packageLength, totalLength,
                head2Container);
        navShow(hits, cat, first, last, packageLength, totalLength,
                footContainer);
    },

    create = function () {
        var html, id = cat.id,
        catName;
        name = "vkCatHits-" + id;
        catName = cat.nameGet();
        zumAnfang =
          '<a href="#" title="Zum Seitenanfang">' + 
            ' <img src="images/arrow-up.png" align="right" ' + 
                  'style="border: 0pt; padding: 0pt 5px;">' + 
          '<\/a>';
        html =
          '<div class="vkBox" name="' + name + '">' + "\n" + 
            '<a name="' + name + '"><\/a>' + "\n" + 
            '<div class="CatHitsBox">' + "\n" + 
            '<div class="CatHitsHead">' +
              zumAnfang + catName + 
            '<\/div>' + "\n" + 
            '<div class="CatHitsHead2">' + "\n" + 
              '<div>&nbsp;<\/div>' + "\n" + 
            '<\/div>' + "\n" + 
            '<div class="CatHits">&nbsp;<\/div>' + "\n" + 
            '<div class="CatHitsFoot">' + zumAnfang + 
              '<div>&nbsp;<\/div>' + "\n" + 
            '<\/div>' + "\n" + 
          '<\/div>';
        cat.updateableAdd(that);
        conf.lang.updateableAdd(that);
        if (conf.prepend) {
            conf.container.prepend($(html));
        }
        else {
            if (conf.predecessor) {
                conf.predecessor.after($(html));
            }
            else if (conf.successor) {
                conf.successor.before($(html));
            }
            else {
                conf.container.append($(html));
            }
        }
        hitsContainer = $("div[name=" + name + "] div.CatHits", 
			  conf.container);
        head2Container = $("div[name=" + name + "] div.CatHitsHead2>div",
                          conf.container);
        footContainer = $("div[name=" + name + "] div.CatHitsFoot>div",
                          conf.container);
        txts = conf.lang.attach(conf.container);
        hitsShow(cat);
    },

    vk_delete = function () {
        conf.lang.updateableRemove(that);
        conf.lang.detach(txts);
        cat.updateableRemove(that);
        hitsRemove();
        $("div[name=vkCatHits-" + cat.id + "]", conf.container).remove();
    },

    packageLength = vkConfHits.packageLength,

    update = function (cat, args) {
        var hint = args ? (args.hint ? args.hint : null) : null;
        if (hint === 'hits') {
            $('div.wait', footContainer).empty();
            hitsShow(cat);
        }
        else if (hint === 'query-extern') {
            $('div.wait', footContainer).empty();
            queryShow(cat, args.query);
        }
        else if (hint === 'lang') {
            $("div.basket", hitsContainer).removeClass("ltr");
            $("div.basket", hitsContainer).removeClass("rtl");
            $("div.basket", hitsContainer).addClass(conf.lang.dir());
        }
        else if (hint === 'searching') {
            hitsContainer.empty();
            $('div.wait', head2Container).html('<img src="images/waits.gif">');
            $('div.wait', footContainer).html('<img src="images/waits.gif">');
        }
        else if (hint === 'search-error') {
            hitsRemove();
            footContainer.text("Fehler");
        }
    },
    vwBoxGet = function () {
        return ($('div.vkBox[name=' + name + ']', conf.container));
    };

    that.catGet = catGet;
    that.create = create;
    that.vk_delete = vk_delete;
    that.update = update;
    that.vwBoxGet = vwBoxGet;

    create();
    return (that);
};


var VKViewCatsHits = function (conf) {
    var that = VKView(conf),
    cats = conf.cats,
    container,
    vws = [],

    create = function () {
        var cat, catsList, html, i, selectedCats, vw;
        catsList = cats.listGet();
        html =
        '<div class="vkBox" name="vkCatsHits">' + 
        //'Treffer:' + 
        '<\/div>';
        selectedCats = cats.selectedGet();

        for (i = 0; i < catsList.length; i += 1) {
            cat = catsList[i];
            cat.updateableAdd(that);
        }
        conf.container.append($(html));
        container = $("div.vkBox[name=vkCatsHits]");
        for (i = 0; i < selectedCats.length; i += 1) {
            cat = selectedCats[i];
            vw = VKViewCatHits({basket: conf.basket,
                                cat: cat,
                                cats: conf.cats,
                                container: container,
                                lang: conf.lang,
                                query: conf.query,
                                queryHistory: conf.queryHistory});
            vws.push(vw);
        }
        conf.searcher.updateableAdd(that);
        if (conf.query === null) {
            container.hide();
        }
    },

    vk_delete = function () {
        container.remove();
    },

    update = function (cat, args) {
        var i, selectedCats, vw, vwBefor;
        if (args.hint === 'searching') {
            container.show();
            conf.searcher.updateableRemove(that);
            return;
        }
        else if (args.hint === 'query-extern') {
            container.show();
            conf.searcher.updateableRemove(that);
            return;
        }
        selectedCats = cats.selectedGet();
        if (vws.length === selectedCats.length) {
            return;
        }
        if (cat.isSelected()) {
            for (i = 0; i < selectedCats.length; i += 1) {
                if (selectedCats[i] === cat) {
                    if (selectedCats.length === 1) {
                        vw = VKViewCatHits({basket: conf.basket,
                                            cat: cat,
                                            cats: conf.cats,
                                            container: container,
                                            lang: conf.lang,
                                            query: conf.query,
                                            queryHistory: conf.queryHistory});
                        vws.splice(i, 0, vw);
                    }
                    else { // selectedCats and vws length > 1
                        if (i === 0) {
                            vw = VKViewCatHits({basket: conf.basket,
                                                cat: cat,
                                                cats: conf.cats,
                                                container: container,
                                                lang: conf.lang,
                                                successor:
                                                  vws[0].vwBoxGet(),
                                                query: conf.query,
                                                queryHistory: conf.queryHistory});
                            vws.splice(i, 0, vw);
                        }
                        else {
                            vw = VKViewCatHits({basket: conf.basket,
                                                cat: cat,
                                                cats: conf.cats,
                                                container: container,
                                                lang: conf.lang,
                                                predecessor:
                                                vws[i - 1].vwBoxGet(),
                                                query: conf.query,
                                                queryHistory: conf.queryHistory});
                            vws.splice(i, 0, vw);
                        }
                        break;
                    }
                }
            }
        }
        else {
            for (i = 0; i < vws.length; i += 1) {
                if (vws[i].catGet() === cat) {
                    vws[i].vk_delete();
                    vws.splice(i, 1);
                    break;
                }
            }
        }
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.update = update;

    create();

    return (that);
};


var VKViewSearch = function (conf) {
    var that = VKView(conf),
    cnt,
    queryVw,
    catsHits,
    catsSel,

    create = function () {
        var html, queryCnt, catsSelCnt, catsHitsCnt;
        html =
        '<div class="vkBox" name="vkSearch">' +
        //  'Suche:' +
        '<\/div>';
        conf.container.append($(html));
        cnt = $("div[name=vkSearch]", conf.container);
        html = 
        '<table id="searchCnt">' + "\n" +
          '<tr>' + "\n" +
            '<td id="queryCnt"><\/td>' + "\n" +
            '<td id="catsSelCnt"rowspan="2"><\/td>' + "\n" +
          '<\/tr>' + "\n" +
          '<tr>' + "\n" +
            '<td id="catsHitsCnt"><\/td>' + "\n" +
          '<\/tr>' + "\n" +
        '<\/table>';
        cnt.append($(html));
        queryCnt = $("table td#queryCnt", cnt);
        catsSelCnt = $("table td#catsSelCnt", cnt);
        catsHitsCnt = $("table td#catsHitsCnt", cnt);
        queryVw = VKViewQuery({cats: conf.cats,
                               container: queryCnt,
                               menu: conf.menu,
                               mat: conf.mat,
                               query: conf.query,
                               queryHistory: conf.queryHistory,
                               searcher: conf.searcher});
        catsSel = VKViewCatsSelTree({cats: conf.cats,
                                     container: catsSelCnt,
                                     mat: conf.mat,
                                     lang: conf.lang,
                                     queryHistory: conf.queryHistory,
                                     menu: conf.menu,
                                     queryVwA: queryVw.vwA});
        catsHits = VKViewCatsHits({basket: conf.basket,
                                   cats: conf.cats,
                                   container: catsHitsCnt,
                                   lang: conf.lang,
                                   queryHistory: conf.queryHistory,
                                   query: conf.query,
                                   searcher: conf.searcher});
        queryVw.search();
    },
    vk_delete = function () {
        catsHits.vk_delete();
        catsSel.vk_delete();
        queryVw.vk_delete();
        conf.menu.updateableRemove(that);
        $("div[name=vkSearch]", conf.container).remove();
    },
    hide = function () {
        cnt.hide();
    },
    show = function () {
        cnt.show();
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.hide = hide;
    that.show = show;

    create();

    return (that);
};


var VKViewHelp = function (conf) {
    var that = VKView(conf),
    cnt,

    create = function () {
        var html = 
          '<div class="vkBox" name="vkHelp" style="display:none;">' + "\n" +
            'Hilfe:' + "\n" +
          '<\/div>';
        conf.container.append($(html));
        cnt = $("div.vkBox[name=vkHelp]", conf.container);
    },

    vk_delete = function () {
        $("div[name=vkHelp]", conf.container).remove();
    },

    hide = function () {
        cnt.hide();
    },

    show = function () {
        cnt.show();
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.hide = hide;
    that.show = show;

    create();

    return (that);
};


var VKViewBasketURL = function (conf) {
    var that = VKView(conf),
    cont,
    filling = false,

    create = function () {
        var html;
        html = 
        '<div class="vkBox" id="basketURL">' + '\n' + 
          '<a href="" title="' + 'Permalink für die aktuelle Merkliste' + 
            '"></a>' + '\n' + 
        '</div>';
        conf.cont.prepend($(html));
        cont = $("div#basketURL", $(conf.cont));
        conf.basket.updateableAdd(that);
    },

    vk_delete = function () {
        cont.remove();
    },

    hide = function () {
        cont.hide();
    },

    linkClear = function () {
        $("a", cont).empty();
        $("a", cont).attr("href", "");
        $("a", cont).removeClass('permalink');
    },

    linkUpdate = function () {
        var url;
        url = conf.basket.urlGet();
        if (url === "") {
            linkClear();
        }
        else {
            url += vkStyles.urlPart();
            $("a", cont).attr("href", url);
            $("a", cont).html('Permalink für die Merkliste');
            $("a", cont).addClass('permalink');
        }
    },

    show = function () {
        cont.show();
    },

    update = function (src, args) {
        if (args.hint === 'basket-filling') {
            filling = true;
        }
        else if (args.hint === 'basket-filled') {
            filling = false;
            linkUpdate();
        }
        else if (args.hint === 'basket-error') {
            linkClear();
        }
        else if (args.hint === 'basket-add') {
            if (!filling) {
                linkUpdate();           
            }
        }
        else if (args.hint === 'basket-remove') {
            linkUpdate();               
        }
        else if (args.hint === 'basket-clear') {
            linkClear();
        }
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.hide = hide;
    that.show = show;
    that.update = update;

    create();

    return (that);
};


var VKViewBasketCntrl = function (conf) {
    var that = VKView(conf),
    cnt,
    vwBURL,
    basketClear = function () {
        var hit, i, url, params;
        conf.basket.clear();
        url = "searcher/clearBasket";
        params = {sid: VKSid()};
        $.ajax({url: url,
                type: 'POST',
                dataType: 'text',
                data: params,
                success: function () {},
                error: function (xhr, status, exception) {}
            }); 
        /*
        basketMailtoDisable();
        basketPrintDisable();
        basketSaveDisable();
        basketClearDisable();   
        basketURLSet();
        */
        return (false);
    },
    addRem = function () {
        $("div.rem input").each(function (n) {
                var val = this.value;
                if (val.match(/^\s*$/)) {
                    $(this).parent().addClass('empty');
                }
                else {
                    $(this).parent().removeClass('empty');
                }
                $("span.rem", $(this).parent()).text(val);
            });
    },
    basketMailto = function () {
        var url, mailto, address, sort, params, html, basketMailtoInfoClear;

        basketMailtoInfoClear = function () {
            $("span#mailed").css('display', 'none');
            $("span#mailed").text("");
        };

        addRem();

        html = $("div[name=vkBasketHits]", conf.container).html();

        url = "basket.html";
        mailto = $('input#mailto', cnt);
        address = mailto[0].value;
        if (address === '') {
            alert("E-Mailadresse fehlt");
            return (false);
        }
        $("span#mailed").text("bearbeiten");
        $("span#mailed").css('display', 'inline');
        sort = 0;
        params = {sid: VKSid(),
                  req: 'mailto',
                  addr: address,
                  sort: sort,
                  html: html};
        $.ajax({url: url,
                type: 'POST',
                dataType: 'text',
                data: params,
                success: function (stat) {
                    if (stat.match(/^\s*ok\s*$/)) {
                        $("span#mailed").text("verschickt");
                    }
                    else {
                        $("span#mailed").text("Fehler");
                    }
                    // $("span#mailed").css('display', 'inline');
                    setTimeout(basketMailtoInfoClear, 3 * 1000);
                },
                error: function (xhr, status, exception) {
                    var error = true;
                }
            }); 
        return (false);
    },
    basketRenew = function () {
        var ok, url, params;
        url = "basket.html";
        params = {req: 'renew'};
        $.ajax({url: url,
                type: 'GET',
                dataType: 'html',
                data: params,
                success: function () {
                    ok = true;
                    conf.basketVw.lifetimeUpdate();
                },
                    error: function (xhr, status, exception) {
                    ok = false;
                }}); 
        return (false);
    },
    basketPrint = function () {
        addRem();
        window.print();
        return (false);
    },
    submit = function (event) {
        basketMailto();
        return (false);
    },
    submitEnter = function (event) {
        var form;
        if (event.keyCode === 13) {
            form = $(this).parents().find('form')[0];
            $(form).submit();
            return false;
        }
        else {
            return true;
        }
    },
    create = function () {
        var html;
        html =
        '<div class="vkBox" name="vkBasketCntrl">' + "\n" + 
          // 'Merkliste Steuerung:' + "\n" + 

          '<div id="basketFunctsContainer">' + "\n" + 
            '<form action="#">' + "\n" + 
              '<table>' + "\n" + 
                '<tr>' + "\n" + 
                  '<td>' + "\n" + 
                    'Merkliste als E-Mail' + "\n" + 
                  '<\/td>' + "\n" + 
                  '<td>' + "\n" + 
                    '<span id="mailed" style="display: none;">' + "\n" + 
                      //'erledigt.' + "\n" + 
                    '<\/span>' + "\n" + 
                  '<\/td>' + "\n" + 
                '<\/tr>' + "\n" + 
                '<tr>' + "\n" + 
                  '<td style="white-space: nowrap;">' + "\n" + 
                    'an' + ' ' + "\n" + 
                    '<input id="mailto" type="text" size="20" value="">' + "\n" + 
                  '<\/td>' + "\n" + 
                  '<td>' + "\n" + 
                    '<input id="mailto_submit" type="submit" ' + "\n" + 
                           'value="' + 'versenden' + '">' + "\n" + 
                  '<\/td>' + "\n" + 
                '<\/tr>' + "\n" + 
                '<tr>' + "\n" + 
                  '<td>' + "\n" + 
                    '<input id="basket_print_submit" ' + "\n" + 
                           'type="submit" value="' + 'Merkliste drucken' + '">' + "\n" + 
/*
                    '<input id="save_submit" type="submit" ' + "\n" + 
                           'value="' + 'Merkliste speichern' + '" disabled>' + "\n" + 
*/
                    '<input id="basket_clear_submit" ' + "\n" + 
                           'type="submit" value="' + 'Merkliste löschen' + '">' + "\n" + 
                  '<\/td>' + "\n" + 
                '<\/tr>' + "\n" + 
/*              
                '<tr>' + "\n" + 
                  '<td>' + "\n" + 
                    'Lebenszeit in Minuten' + "\n" + 
                    '<span id="basketLifetime">' + 
                    '<\/span>' + "\n" + 
                  '<\/td>' + "\n" + 
                  '<td>' + "\n" + 
                    '<input id="basket_renew_submit" ' + "\n" + 
                           'type="submit" value="verlängern">' + "\n" + 
                  '<\/td>' + "\n" + 
                '<\/tr>' + "\n" + 
*/
              '<\/table>' + "\n" + 
            '<\/form>' + "\n" + 
            '<br>' + "\n" + 
          '<\/div>' + "\n" + 

        '<\/div>';
        conf.container.append($(html));
        cnt = $("div.vkBox[name=vkBasketCntrl]", conf.container);
        vwBURL = VKViewBasketURL({basket: conf.basket, cont: cnt});
        $("input#basket_clear_submit", cnt).click(basketClear);
        $("input#mailto_submit", cnt).click(basketMailto);
        $("input#basket_print_submit", cnt).click(basketPrint);
        $("input#mailto", cnt).bind('keypress', submitEnter);
        $("form", cnt).bind('submit', submit);
        $("input#basket_renew_submit", cnt).click(basketRenew);
        conf.basket.updateableAdd(that);
        conf.basketVw.lifetimeUpdate();
        window.setTimeout(conf.basketVw.lifetimeUpdate, 30000);
    },
    vk_delete = function () {
        // cnt.remove();
        conf.basket.updateableRemove(that);
        conf.vwH.hitsRemove();
    },
    update = function (basket, args) {
        if (conf.basket.length() > 0) {
            $("input", cnt).removeAttr("disabled");
        }
        else {
            $("input", cnt).attr("disabled", "disabled");
        }
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.update = update;

    create();

    return (that);
};


var VKViewBasketHits = function (conf) {
    var that = VKView(conf),
    cnt,
    filling = false,
    hitsCnt,
    vws = [],

    create = function () {
        var html;
        html =
        '<div class="vkBox" name="vkBasketHits">' + "\n" + 
          // 'Merkliste:' + "\n" + 
          '<div class="vkHits">' + "\n" + 
            // 'Merkliste Hits:' + "\n" + 
          '<\/div>' + "\n" + 
        '<\/div>';
        conf.container.append($(html));
        cnt = $("div.vkBox[name=vkBasketHits]", conf.container);
        hitsCnt = $("div.vkHits", cnt);
        // hitsShow();
        conf.basket.updateableAdd(that);
    },

    vk_delete = function () {
        conf.basket.updateableRemove(that);
        cnt.remove();
    },

    hitsRemove = function () {
        var vw = null;
        while (true) {
            vw = vws.shift();
            if ((vw === undefined) || (vw === null)) {
                break;
            }
            vw.vk_delete();
        }
    },

    hitsShow = function (cat) {
        var hits, first, last, length, i, html, vw;
        hits = conf.basket.hitsGet();
        if (!hits) {
            return;
        }
        first = 1;
        length = hits.length;
        last = first + length - 1;
        hitsRemove();
        for (i = 0; i < length; i += 1) {
            vw = VKViewCatHit({basket: conf.basket,
                               basketCnt: true,
                               cat: hits[i][0],
                               cats: conf.cats,
                               container: hitsCnt,
                               hit: hits[i][1],
                               lang: conf.lang,
                               no: first + i,
                               pos: i,
                               queryHistory: conf.queryHistory});
            vws.push(vw);
        }
    },

    update = function (basket, args) {
        // alert(args.hint);
        if (args.hint === 'basket-filling') {
            hitsRemove();
            hitsCnt.append($('<span class="wait">' + 
                             '<img src="images/waits.gif"><\/span>'));
            filling = true;
        }
        else if (args.hint === 'basket-filled') {
            filling = false;
            $("span.wait", hitsCnt).remove();
            hitsShow();
            conf.basketVw.lifetimeUpdate();
        }
        else if (args.hint === 'basket-error') {
            hitsCnt.append($('<span>Fehler<\/span>'));
        }
        else if (args.hint === 'basket-add') {
            if (!filling) {
                hitsRemove();
                hitsShow();
            }
        }
        else if (args.hint === 'basket-remove') {
            hitsRemove();
            hitsShow();
        }
        else if (args.hint === 'basket-clear') {
            hitsRemove();
        }
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.hitsShow = hitsShow;
    that.hitsRemove = hitsRemove;
    that.update = update;

    create();

    return (that);
};


var VKViewBasket = function (conf) {
    var that = VKView(conf),
    cnt,
    innerCnt,
    hitsCnt,
    vwH,
    vwC,

    create = function () {
        var date, html, vw;
        date = new Date();
        html =
        '<div class="prt">' + "\n" + 
          '<h1>medien buehne film - Meine Merkliste<\/h1>' + "\n" + 
          '<h2>Erzeugt am: ' + date.getDate() + '.' + (1 + date.getMonth()) + '.' + 
              (1900 + date.getYear()) + '<\/h2>' + "\n" + 
        '<\/div>' + "\n" + 
        '<div class="vkBox" name="vkBasket" style="display:none;">' + "\n" + 
          '<div class="hits">' + "\n" + 
          '<\/div>' + "\n" + 
        '<\/div>';
        conf.container.append($(html));
        cnt = $("div.vkBox[name=vkBasket]", conf.container);
        innerCnt = $("div.hits", cnt);
        vwH = VKViewBasketHits({basket: conf.basket,
                                basketVw: that,
                                cats: conf.cats,
                                container: innerCnt,
                                lang: conf.lang,
                                mat: conf.mat,
                                menu: conf.menu,
                                mode: conf.mode,
                                queryHistory: conf.queryHistory});
        vwC = VKViewBasketCntrl({basket: conf.basket,
                                 basketVw: that,
                                 cats: conf.cats,
                                 container: innerCnt,
                                 lang: conf.lang,
                                 mat: conf.mat,
                                 menu: conf.menu,
                                 mode: conf.mode,
                                 queryHistory: conf.queryHistory,
                                 vwH: vwH});
        conf.basket.fill();
    },

    vk_delete = function () {
        vwC.vk_delete();
        vwH.vk_delete();
        cnt.remove();
    },

    hide = function () {
        cnt.hide();
    },

    lifetimeUpdate = function () {
        var ok, url, params;
        url = "basket.html";
        params = {req: 'lifetime'};
        $.ajax({url: url,
                type: 'GET',
                dataType: 'text',
                data: params,
                success: function (lifetime) {
                    ok = true;
                    $("span#basketLifetime").text(lifetime);
                },
                error: function (xhr, status, exception) {
                    ok = false;
                }}); 
        return (false);
    },

    show = function () {
        cnt.show();
        // $("div.prt").css("display", "normal")
        // vwH.hitsShow();
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.hide = hide;
    that.lifetimeUpdate = lifetimeUpdate;
    that.show = show;

    create();

    return (that);
};


var VKViewPage = function (conf) {
    var that = VKView(conf),
    vwMenu = null,
    mode = null,
    vwBasket,
    vwHelp,
    vwLang,
    vwSearch,

    update = function (src, args) {
        var menu, newMode;
        if (args.hint === "menu") {
            menu = src;
            newMode = menu.selectionGet();
            if (newMode === mode) {
                return;
            }
            mode = newMode;
            if ((newMode === "simpleSearch") || (mode === "advancedSearch")) {
                vwBasket.hide();
                vwHelp.hide();
                vwSearch.show();
            }
            else if (newMode === "basket") {
                vwSearch.hide();
                vwHelp.hide();
                vwBasket.show();
            }
            else if (newMode === "help") {
                vwSearch.hide();
                vwBasket.hide();
                vwHelp.show();
            }
            else {
            }
        }
    },

    create = function () {
        vwLang = VKViewLang({cnt: conf.container,
                                 lang: conf.lang});
        conf.lang.updateableAdd(that);
        vwMenu = VKViewMenu(conf);
        vwMenu.updateableAdd(that);
        vwSearch = VKViewSearch({basket: conf.basket,
                                 cats: conf.cats,
                                 container: conf.container,
                                 lang: conf.lang,
                                 mat: conf.mat,
                                 menu: vwMenu,
                                 mode: mode,
                                 query: conf.query,
                                 queryHistory: conf.queryHistory,
                                 searcher: conf.searcher});
        vwBasket = VKViewBasket({basket: conf.basket,
				 cats: conf.cats,
				 container: conf.container,
				 lang: conf.lang,
				 mat: conf.mat,
				 menu: vwMenu,
				 mode: mode,
				 queryHistory: conf.queryHistory});
        vwHelp = VKViewHelp(conf);
        update(vwMenu, {hint: "menu"});
    },
    vk_delete = function () {
    };

    that.create = create;
    that.vk_delete = vk_delete;
    that.update = update;

    create();

    return (that);
};
