function SuggestField(name, labelColumns) {
    this.suggestPrefix = function () {
        return this.name + "-suggest-";
    }

    this.determineTable = function () {
        return this.element.getElementsByTagName("table")[0].parentNode.table;
    }

    this.linkClicked = function (event) {
        var suggestPrefix = this.suggestPrefix();
        var suggestDiv = document.getElementById(suggestPrefix + "div");
        var suggestField = document.getElementById(suggestPrefix + "text");

        suggestDiv.style.display = "block";

        if (suggestField != null) {
            suggestField.focus();
            updateSuggestions(suggestPrefix);
        }

        getEvent(event).stopHandling();
    }

    this.makeRowsInteractive = function (table) {
        for (var i = 0; i < table.tBodies.length; i++) {
            var body = table.tBodies[i];

            for (var j = 0; j < body.rows.length; j++) {
                row = body.rows[j];
                row.onclick = this.createRowClickedHandler(row);
                row.onmouseover = this.createRowHotHandler(row, true);
                row.onmouseout = this.createRowHotHandler(row, false);

                assureNodeClass(row, "suggest-row");
            }
        }
    }

    this.createRowClickedHandler = function (row) {
        var field = this;

        return function (event) {
            field.rowClicked(event, row);
        };
    }

    this.createRowHotHandler = function (row, hot) {
        return function (event) {
            setHot(row, event, hot);
        };
    }

    this.closeClicked = function (event) {
        var suggestDiv = document.getElementById(this.suggestPrefix() + "div");
        suggestDiv.style.display = "none";
        getEvent(event).stopHandling();
    }

    this.clearClicked = function (event) {
        this.updateValue("0", "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;");
        getEvent(event).stopHandling();
    }

    this.nextClicked = function (event) {
        var suggestPrefix = this.suggestPrefix();
        var suggestOffset = document.getElementById(suggestPrefix + "offset");

        suggestOffset.value = parseInt(suggestOffset.value) + 10;
        updateSuggestions(suggestPrefix);
        getEvent(event).stopHandling();
    }

    this.previousClicked = function (event) {
        var suggestPrefix = this.suggestPrefix();
        var suggestOffset = document.getElementById(suggestPrefix + "offset");
        
        suggestOffset.value = Math.max(parseInt(suggestOffset.value) - 10, 0);
        updateSuggestions(suggestPrefix);
        getEvent(event).stopHandling();
    }

    this.constructLabel = function (row) {
        var labels = new Array();
        var displayLabelColumnIndices = this.labelColumns;

        for (var i = 0; i < displayLabelColumnIndices.length; i++) {
            var columnValue = "<span>" + row.cells[displayLabelColumnIndices[i]].innerHTML + "</span>";

            if (columnValue !== "")
                labels.push(columnValue);
        }

        return labels.join("");
    }

    this.rowClicked = function (event, row) {
        var event = getEvent(event);
        var eventSource = event.getSource();

        if (!isLink(eventSource)) {
            var value = getInnerText(row.cells[0]);
            var label = this.constructLabel(row);

            this.updateValue(value, label);
            event.stopHandling();
        }
    }

    this.updateValue = function (value, displayValue) {
        var suggestPrefix = this.suggestPrefix();
        var suggestLink = document.getElementById(suggestPrefix + "link");
        var suggestDiv = document.getElementById(suggestPrefix + "div");
        var suggestField = document.getElementById(this.name);

        suggestField.value = value;

        suggestLink.innerHTML = displayValue;
        suggestDiv.style.display = "none";
        suggestLink.focus();
    }

    this.findRowWithId = function (table, id) {
        var result = null;
        var i = 1;

        while (result === null && i < table.rows.length) {
            var row = table.rows[i];

            if (getInnerText(row.cells[0]) == id)
                result = row;
            else
                i++;
        }

        return result;
    }

    this.createOnTableChangedHandler = function () {
        var field = this;

        return function (newTable) {
            field.tableChanged(newTable);
        }
    }

    this.tableChanged = function (newTable) {
        this.makeRowsInteractive(newTable);
    }

    this.initialize = function () {
        this.table.onChanged = this.createOnTableChangedHandler();

        var prefix = this.suggestPrefix();
        var table = this.table.getTableElement();
        var suggestField = document.getElementById(this.name);
        
        this.makeRowsInteractive(table);

        if (suggestField.value !== "") {
            var row = this.findRowWithId(table, suggestField.value);

            if (row !== null) {
                var suggestLink = document.getElementById(prefix + "link");
                suggestLink.innerHTML = this.constructLabel(row);
            }
        }
    }

    this.name = name;
	this.labelColumns = labelColumns;
    this.element = getParentNode(getCurrentScript(), "div");
    this.table = this.determineTable();

    this.initialize();
}

