var FormBuilder = Class.create({
    container: null,
    isEditing: false,
    urlScheme: "http://",
    title: null,
    description: null,
    fieldsets: null,
    properties: null,
    elements: null,
    paymentInfo: null,

    initialize: function(container, isEditing, formdata, urlScheme) {
        //Set the form container
        if (typeof container == "string")
            this.container = $(container);
        else
            this.container = container;

        this.isEditing = isEditing;

        if (urlScheme)
            this.urlScheme = urlScheme;

        //Load the form db information
        this.paymentInfo = formdata.data.paymentInfo;
        this.properties = formdata.data.properties;
        this.elements = formdata.data.elements;
        this.fieldsets = new Array();

        //Show the price fields if the form has payment info
        if (this.paymentInfo)
            this.container.addClassName("paymentForm");

        //Build the GUI
        this.BuildForm();
    },

    BuildForm: function(dataSource) {
        //Construct the header
        var header = new Element("div", { "class": "formHeader" });
        try {
            this.title = new Element("h2", { "class": "formTitle" }).update(this.properties.title);
        } catch (Error) {
            this.title = new Element("h2", { "class": "formTitle" }).update(this.properties.title.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, ''));
        }
        try {
            this.description = new Element("p", { "class": "formDescription" }).update(this.properties.description);
        } catch (Error) {
            this.description = new Element("p", { "class": "formDescription" }).update(this.properties.description.stripTags());
        }
        header.insert(this.title);
        header.insert(this.description);

        //Add the header to the container.
        this.container.insert(header);

        //Go through each element and add the row to the container
        if (this.elements != null)
        this.elements.each(function(fieldData) {
            fieldData.isCaptcha = (fieldData.formElementID == this.properties.captchaFieldsetID);
            this.insertFieldset(fieldData, true);
        }, this);
    },

    insertFieldset: function(fieldData, addToArray, addIndex) {
        //Construct the structure of the fieldset
        var row_container = new Element("div", { "class": "fieldItem type-" + fieldData.fieldType });
        if (fieldData.cssClass) {
            fieldData.cssClass.each(function(css, index) {
                row_container.addClassName(css);
            }, this);
        }
        var row_content = new Element("div", { "class": "fieldItemInner" });
        var row_title = new Element("div", { "class": "fieldTitle" }).update("<span class=\"title\">" + fieldData.fieldTitle + "</span><span class=\"req\">" + (fieldData.isRequired ? "*" : "") + "</span><em class=\"uni\">" + (fieldData.isUnique ? "(unique)" : "") + "</em>");
        var row_instructions = new Element("div", { "class": "fieldInstructions" }).update(fieldData.instructions ? fieldData.instructions : "");

        //Dumb IE Fix
        var optionsChecked = new Array();

        row_container.fieldTitle = row_title;
        row_container.instructions = row_instructions;

        row_content.insert(row_title);
        row_content.insert(this.BuildFields(fieldData, row_container, addIndex, optionsChecked));
        row_content.insert(row_instructions);
        row_container.insert(row_content);

        this.container.insert(row_container);

        //Dumb IE Fix - it will only allow radios and checkboxes to be selected if already appended to the dom
        optionsChecked.each(function(opt, index) {
            $(opt).checked = true;
        }, this);

        //Add this fieldset to the array
        if (addToArray)
            this.fieldsets.push(row_container);
        else
            return row_container;
    },

    BuildFields: function(template, fieldset, addIndex, optionsChecked) {
        var content = new Element("div", { "class": "fieldContent" });

        var cRow = 0; //Stores the current row
        var cRowObj = new Element("p", { "class": "fieldRow" });

        //Add the field array to the fieldset
        Object.extend(fieldset, { fields: new Array() });

        //Build each field and keep track of which row the field is on.
        template.fields.each(function(field, index) {
            //Check if we need to create another fieldRow.
            if (cRow != field.fieldRow) {
                content.insert(cRowObj);
                cRow = field.fieldRow;
                cRowObj = new Element("p", { "class": "fieldRow" });
            }

            //Create the field structure
            var block = new Element("span", { "class": "fieldBlock" });
            var name = new Element("label", { "class": "fieldName" }).update(field.name ? field.name : "");
            var note = new Element("em", { "class": "fieldNote" }).update(field.fieldNote ? field.fieldNote : "");

            //Create the input field
            var input;
            var fieldName = "field_" + this.properties.formID + "_" + (addIndex ? addIndex : field.fieldID);
            switch (field.type) {
                case "text":
                    input = new Element("input", {
                        "name": fieldName,
                        "type": "text",
                        "size": field.size,
                        "class": "textField " + $A(field.cssClass).join(" ") + (field.isRequired ? " required validate-" + field.type : ""),
                        "value": (field.defaultValue ? field.defaultValue : "")
                    });
                    break;
                case "radio":
                    input = new Element("span", { "class": field.type + "-container" });
                    field.options.each(function(choice, index) {
                        var choice_row = new Element("span", { "class": "choice-option" });
                        var choice_label = new Element("label", { "for": fieldName + "_option_" + index }).update(choice.text);
                        var choice_input = new Element("input", {
                            "id": (fieldName + "_option_" + index),
                            "name": fieldName,
                            "checked": (choice.isDefault ? true : false),
                            "type": field.type,
                            "value": choice.text
                        });
                        choice_input.optionID = choice.optionID;

                        if (choice.isDefault)
                            optionsChecked.push(choice_input.id);

                        if (this.paymentInfo)
                            choice_input.addClassName("priceField");

                        choice_row.insert(choice_input);
                        choice_row.insert(choice_label);
                        input.insert(choice_row);
                    }, this);
                    break;
                case "checkbox":
                    input = new Element("span", { "class": field.type + "-container" });
                    field.options.each(function(choice, index) {
                        var choice_row = new Element("span", { "class": "choice-option" });
                        var choice_label = new Element("label", { "for": fieldName + "_option_" + index }).update(choice.text);
                        var choice_input = new Element("input", {
                            "id": (fieldName + "_option_" + index),
                            "name": (fieldName + "_option_" + index),
                            "type": field.type,
                            "class": "checkbox",
                            "checked": (choice.isChecked ? true : false),
                            "value": choice.text
                        });
                        if (!choice_input.value || choice_input.value == "")
                            choice_input.value = "checked";
                        choice_input.optionID = choice.optionID;

                        if (choice.isChecked)
                            optionsChecked.push(choice_input.id);

                        if (this.paymentInfo)
                            choice_input.addClassName("priceField");

                        choice_row.insert(choice_input);
                        choice_row.insert(choice_label);
                        input.insert(choice_row);
                    }, this);
                    break;
                case "country":
                    input = this.BuildDropDownWithImage(fieldName, Country.data, "country", field.defaultValue);
                    break;
                case "state":
                    input = this.BuildDropDown(fieldName, US_States.data, "states");
                    input.value = (field.defaultValue ? field.defaultValue : "");
                    break;
                case "email":
                    input = new Element("input", {
                        "name": fieldName,
                        "type": "text",
                        "size": field.size,
                        "class": "textField " + $A(field.cssClass).join(" ") + (field.isRequired ? " required validate-" + field.type : ""),
                        "value": (field.defaultValue ? field.defaultValue : "")
                    });
                    break;
                case "website":
                    input = new Element("input", {
                        "id": fieldName,
                        "name": fieldName,
                        "type": "text",
                        "size": field.size,
                        "class": "textField " + $A(field.cssClass).join(" ") + (field.isRequired ? " required validate-" + field.type : ""),
                        "value": (field.defaultValue ? field.defaultValue : "")
                    });
                    break;
                case "select":
                    input = this.BuildDropDown(fieldName, field.options);

                    if (this.paymentInfo)
                        input.addClassName("priceField");

                    if (field.defaultValue && field.defaultValue != "")
                        input.value = field.defaultValue;
                    break;
                case "currency":
                    input = new Element("input", {
                        "name": fieldName,
                        "type": "text",
                        "size": field.size,
                        "class": "textField " + $A(field.cssClass).join(" ") + (field.isRequired ? " required validate-" + field.type : ""),
                        "value": (field.defaultValue ? field.defaultValue : "")
                    });
                    break;
                case "number":
                    input = new Element("input", {
                        "name": fieldName,
                        "type": "text",
                        "size": field.size,
                        "class": "textField " + $A(field.cssClass).join(" ") + (field.isRequired ? " required validate-" + field.type : ""),
                        "value": (field.defaultValue ? field.defaultValue : "")
                    });
                    break;
                case "textarea":
                    input = new Element("textarea", {
                        "name": fieldName,
                        "rows": (field.rows ? field.rows : 6),
                        "cols": ((field.size && field.size > 0) ? field.size : 46),
                        "class": "textField " + $A(field.cssClass).join(" ") + (field.isRequired ? " required validate-" + field.type : "")
                    });
                    input.value = (field.defaultValue ? field.defaultValue : "");
                    break;
                case "filebutton":
                    input = new Element("button", {
                        "name": fieldName,
                        "size": field.size,
                        "class": "textField " + $A(field.cssClass).join(" ")
                    }).update("Upload File");
                    break;
                case "file":
                    input = new Element("input", {
                        "name": fieldName,
                        "type": "file",
                        "size": field.size,
                        "class": "textField " + $A(field.cssClass).join(" ") + (field.isRequired ? " required validate-" + field.type : ""),
                        "value": (field.defaultValue ? field.defaultValue : "")
                    });
                    break;
                case "richtext":
                    input = new Element("span", {
                        "id": fieldName,
                        "class": "",
                        "value": (field.defaultValue ? field.defaultValue : "")
                    });
                    break;
                case "captcha":
                    input = new Element("img", {
                        "src": this.urlScheme + (location.host == "www.icebrrg.com" ? "www.icebrrg.com" : "www.formbldr.com") + "/formHandler/captcha.aspx?width=200&height=50&formID=" + this.properties.formID + (this.properties.captchaCode ? "&code=" + encodeURIComponent(this.properties.captchaCode) : ""),
                        "width": "200",
                        "height": "50"
                    });
                    break;
                default:
                    input = new Element("input", {
                        "name": fieldName,
                        "type": "text",
                        "size": field.size,
                        "class": "textField " + $A(field.cssClass).join(" ") + (field.isRequired ? " required validate-" + field.type : ""),
                        "value": (field.defaultValue ? field.defaultValue : "")
                    });
                    break;
            }
            block.insert(name);
            block.insert(input);
            block.insert(note);

            cRowObj.insert(block);

            //Add the input to the fields array
            fieldset.fields.push({ name: name, field: input, note: note });
        }, this);

        //If we are dealing with a date fieldset then add the datapicker icon to the row.
        if (!this.isEditing && template.fieldType == "date") {
            var dateImageBlock = new Element("span", { "class": "fieldBlock datePickerImage" });
            dateImageBlock.insert(new Element("label", { "class": "fieldName" }).update("&nbsp;"));
            var dateImage = new Element("img", { "src": this.urlScheme + "www.icebrrg.com/images/cal.gif" })
            dateImage.observe("click", function(event, rowObj) {
                DatePickerManager.Show(Event.element(event), rowObj);
                event.stop();
            } .bindAsEventListener(this, cRowObj));
            dateImage.rel = template.formatType;
            dateImageBlock.insert(dateImage);
            dateImageBlock.insert(new Element("em", { "class": "fieldNote" }).update("&nbsp;"));
            cRowObj.insert(dateImageBlock);
        }
        content.insert(cRowObj);
        return content;
    },

    BuildDropDown: function(name, DataSource, type, defaultValue) {
        var dropdown = new Element("select", { "name": name, "class": "dropdown " + type, "multiple": (type == "multiple") });

        DataSource.each(function(choice, index) {
            var option = new Element("option", { "value": (choice.value ? choice.value : choice.text) }).update(choice.text);
            option.selected = (choice.isDefault ? true : false);
            option.optionID = choice.optionID;
            dropdown.insert(option);
        }, this);

        if (defaultValue)
            dropdown.value = defaultValue;

        return dropdown;
    },

    BuildDropDownWithImage: function(id, DataSource, type, defaultValue) {
        var dd_container = new Element("div", { "class": "dropdown-image-container" });
        var dropdown = this.BuildDropDown(id, DataSource, type, defaultValue);
        var icon_container = new Element("span", { "class": "dropdown-image" });

        dd_container.insert(dropdown);
        dd_container.insert(icon_container);

        return dd_container;
    },

    updateSelectOptionList2: function(selectObj, dataStore, selected, cols) {
        if (!cols)
            cols = ["value", "text"];

        dataStore.each(function(item, index) {
            var option = document.createElement("option");
            option.value = (cols[0] ? item[cols[0]] : index);
            option.appendChild(document.createTextNode(item[cols[1]]));

            if (item[cols[0]] == selected)
                option.selected = "selected";

            selectObj.appendChild(option);
        });
    }
});

JsonBuilder = {
    buildObject: function(json, clean) {
        if(clean)
            json = json.replace(/\\\\/g, "\\"); //prevents santax error
            
        var obj = json.evalJSON(true);
        return obj;
    }
};