/*global $, Ext, Sfr*/
var DataSetComponent = {
   source_configurations: {}, //javascript sucks so much that arrays = hashes
   
   set_configuration: function(uniqueId, config) {
      if (config === null) {
        config = {};
      }
        
      DataSetComponent.source_configurations[uniqueId] = config;
      $('data_source_config_' + uniqueId).value = Ext.encode(config);
   },
   
   get_configuration: function(uniqueId) {
      return DataSetComponent.source_configurations[uniqueId];
   },
   
   //generate a callback delegate
   configuration_callback: function(uniqueId) {
      var scope = {
         uniqueId: uniqueId
      };
      return DataSetComponent.callback_internal.bind(scope);
   },
   
   callback_internal: function(newConfig) {
      if (newConfig !== null) { //null means cancel, so don't change anything
         DataSetComponent.set_configuration(this.uniqueId, newConfig);
      }
   },
   
      
   show_column_picker: function(uniqueId) {
      var win = null;
      if (DataSetComponent.source_configurations[uniqueId].data_source_id === undefined) {
         Ext.Msg.alert("Error", "Please select a data source first.");
         return;
      }


      var prefix_text = new Ext.form.TextField({
         name: "prefix_text",
         fieldLabel: "Optional Prefix",
         anchor: "100%"
      });

      var suffix_text = new Ext.form.TextField({
         name: "suffix_text",
         fieldLabel: "Optional Suffix",
         anchor: "100%"
      });

      var grid_panel = new Ext.grid.GridPanel({
        store: new Ext.data.JsonStore({
              url: '/data/column_info',
              baseParams: {data_source_id: DataSetComponent.source_configurations[uniqueId].data_source_id},
              root: 'columns',
              fields: ['name'],
              autoLoad: true
        }),
        viewConfig: {
           forceFit: true
        },
        columns: [
            {header: "Column", sortable: true, dataIndex: 'name'}
        ],
		  height: 200,
        sm: new Ext.grid.RowSelectionModel({
           singleSelect:true
        }),
        frame: false,
        listeners: {
           rowdblclick: function(grid, row, event) {
                 Sfr.insertAtCursor($('template_' + uniqueId), "{" + prefix_text.getValue() + "^data:"+ grid.getStore().getAt(row).get("name") + "^" + suffix_text.getValue() +"}");
                 //win.close();
           }
        },
        anchor: "100% -50"
     });
      win = new Ext.Window({
           animate: true,
           autoScroll: false,
           closable: true,
           modal: false,
           draggable: true,
           resizable: true,
           constrain: true,
           bodyStyle: "padding: 5px;",
           title: "Column picker",
           width: 280,
           height: 288,
           layout: 'form',
           items: [prefix_text, suffix_text, grid_panel]
      });
      
      win.show();
      
   }
};
 

/*global Data, ExtSfr, Ext, Form, Ajax, Element, $, alert */

var EditDataSourceComponent = {};
EditDataSourceComponent.initialize_edit = function(container_div_id, config) {
   
   var editable_sources = [];
   var current_source_fields = [];
   var field_tree = null;
   
   for (var dsid in Data.source_cache) {
     if (Data.source_cache.hasOwnProperty(dsid)) {
        var ds = Data.source_cache[dsid];
        //only want editable sources
        if (ds.editable) {
           var field_list = [];
           for (var idx in ds.columns) {
              if (ds.columns.hasOwnProperty(idx)) {
                 var column = ds.columns[idx];
                 if (column.editable) {
                    field_list.push(column);
                 }
              }
           }
           if(config.editable_data_source_id === dsid) {
              current_source_fields = field_list;
           }
           editable_sources.push({
              id: dsid,
              name: ds.name,
              fields: field_list
           });
        }
     }
   }
   
   
   var editable_data_source_box = ExtSfr.FormFactory.createComboBox({
      store: new Ext.data.JsonStore({
         data: {sources: editable_sources},
         root: 'sources',
         fields: ['id', 'name', 'fields']
      }),
      name: 'editable_data_source_id_' + container_div_id,
      displayField: 'name',
      valueField: 'id',
      fieldLabel: 'Data Source',
      value: config.editable_data_source_id,
      listeners: {
         select: function(combo, record, e) {
            current_source_fields = record.get('fields');
            field_tree.clearTree();
            field_tree.addItems(record.get('fields'));
         }
      }
   });
   
   
   var editable_fields = new Ext.form.Hidden({
      name: 'editable_fields_' + container_div_id,
      value: config.editable_fields
   });
   
   var no_record_text_field = new Ext.form.TextArea({
      name: 'no_record_text_' + container_div_id,
      value: config.no_record_text || "The record specified could not be found.",
      fieldLabel: "Not Found Error",
      width: 400,
      height: 100
   });

   var flash_message_text_field = new Ext.form.TextArea({
      name: 'flash_message_text_' + container_div_id,
      value: config.flash_message_text || "Your data has been saved.",
      fieldLabel: "Saved Message",
      width: 400,
      height: 100
   });

   var update_editable_fields = function() {
      editable_fields.setValue(Ext.encode(field_tree.getOrderedValues()));
   };
   
   var landing_page_picker = new ExtSfr.FieldWrapper(ExtSfr.FormFactory.createComboBox({
      data_source_id: 'cms_pages',
      auto_load: true,
      fieldLabel: "Landing Page",
      name: 'landing_page_id_' + container_div_id,
      value: config.landing_page_id
   }));
   
   var record_variable = new Ext.form.TextField({
      name: 'record_variable_' + container_div_id,
      fieldLabel: 'Variable to use for record id',
      value: config.record_variable
   });

   field_tree = new ExtSfr.ArrangableList({
      anchor: "100%",
      height: 250,
      data: config.editable_fields,
      editable: true,
      value: "label",
      title: "Fields",
      style: {
         marginTop: "8px",
         marginBottom: "8px"
      },
      listeners: {
         append: update_editable_fields,
         remove: update_editable_fields,
         movenode: update_editable_fields
      },
      customAdd: function() {
         // if there is no data source selected don't do anything
         if(!editable_data_source_box.getValue()){
            return false;
         }
         var checkbox_grid = new ExtSfr.CheckboxGrid({
            store: new Ext.data.SimpleStore({
               fields: ['name', 'label']
            }),
            cm: new Ext.grid.ColumnModel([
               {header: "Label", dataIndex: "label"}
            ]),
            listeners: {
              render: {
                 delay: 200,
                 fn: function () {
                    var cbs = checkbox_grid.getEl().query("input.x-row-checkbox");
                    var i = 0;
                    checkbox_grid.getStore().each(function (record) {
                       field_tree.getRootNode().childNodes.each(function(child) {
                          if(child.text === record.get('label')) {
                             cbs[i].checked = true;
                          }
                       });
                       i++;
                    });
                 }
              }
            }
         });
         
         current_source_fields.each(function(record){
            checkbox_grid.store.add(ExtSfr.record_from_object(record));
         });

         var win = new Ext.Window({
            title: 'Select viewable columns',
            width: 300,
            modal: true,
            height: 500,
            layout: "fit",
            items: checkbox_grid,
            buttons: [
               {
                  text: "Cancel",
                  handler: function () {
                     win.close();
                  }
               },
               {
                  text: 'Save',
                  handler: function () {
                     var cbs = checkbox_grid.getEl().query("input.x-row-checkbox");
                     var i = 0;
                     var existing_nodes = {};
                     var data = [];
                     var remove_data = [];
                     field_tree.getRootNode().childNodes.each(function(child, i) {
                           existing_nodes[child.text] = true;
                     });
                     checkbox_grid.getStore().each(function (record) {
                        if(!(cbs[i].checked)) {
                           remove_data.push({label: record.get('label'), name: record.get('name')});
                        } else if (!(existing_nodes[record.get('label')])) {
                           data.push({label: record.get('label'), name: record.get('name')});
                        }
                        i++;
                     });
                     field_tree.removeItems(remove_data);
                     field_tree.addItems(data);
                     win.close();
                  }
               }
               
            ]
         });
         win.show();
         
      }
   });
   
   var edit_form_panel = new Ext.Panel({
      layout: 'form',
      border: false,
      labelAlign: "top",
      defaults: {
         labelAlign: "top"
      },
      hideMode: 'offsets',
      items: [
         landing_page_picker,
         editable_data_source_box,
         field_tree,
         editable_fields,
         no_record_text_field,
         record_variable,
         flash_message_text_field
      ]
   });
   
   var panel = new Ext.Panel({
      layout: 'form',
      border: false,
      bodyStyle: 'padding: 5px;',
      renderTo: "form_panel_" + container_div_id,
      items: [
         edit_form_panel
      ]
   });

   panel.doLayout();
};

EditDataSourceComponent.reload_value_list = function(from, popup, data_source_id) {
   var params = Form.serialize(popup.form, true);
   
   params.data_source_id = data_source_id;
   params.column_name = popup.name.replace(/^data\[/, '').replace(/\]$/, '');
   
   Form.disable(from);
   Form.disable(popup);
   var result = new Ajax.Request("/data/load_value_list", {
      method: 'post',
      parameters: params,
      onSuccess: function(transport) {
         var result = transport.responseJSON;
         while (popup.options.length) {
            popup.remove(0);
         }
         result.rows.each(function(item){
            //this comes back as an array of {value: "blah"} because that's what
            //ext stores need to consume
            var val = item.value;
            popup.options.add(new Option(val, val));
            
         });
         Form.enable(from);
         Form.enable(popup);
      }
   });
};

EditDataSourceComponent.show_password_fields = function(button) {
   var td = Element.up(button, 'TD');
   
   // enable the fields
   td.down('.fields').select('INPUT').each(function(x) {
      x.enable();
   }); 
   
   // show them
   td.down('.fields').show(); 
   
   // and hide the non-editable version
   td.down('.preview').hide();
};

EditDataSourceComponent.hide_password_fields = function(button) {
   var td = Element.up(button, 'TD');
   
   // disable the fields so they don't submit
   td.down('.fields').select('INPUT').each(function(x) {
      x.disable();
   }); 
   
   // hide the fields
   td.down('.fields').hide(); 
   
   // show the non-editable version
   td.down('.preview').show();
};

EditDataSourceComponent.submit_editable_form = function(form, destination_url, flash_message){
    Form.request(form, {
        onFailure: function(transport) {
           var errors = transport.responseJSON.errors;
           for(var i in errors) {
              if (errors.hasOwnProperty(i)) {
                 var el = $(i.replace(/.*\./, ''));
                 if (el) {
                    el.innerHTML = "<span>" + errors[i] +"</span>";
                 }
              }
           }
        },
        onSuccess: function () {
           if (destination_url) {
              location.href = destination_url;
           }
           else {
              alert(flash_message);
           }
        }
    });
};

EditDataSourceComponent.popup_grid = function(config) {
   var field = $(config.field_id);
   var display = $(config.field_id + "_display");
   config.params = Form.serialize(field.form, true);
   config.callback = function(new_value) {
      field.value = new_value;
      display.innerHTML = new_value;
   };
   EditDataSourceComponent.editable_source_popup_grid(config);
};

EditDataSourceComponent.editable_source_popup_grid = function(config) {
   config.params.data_source_id = config.data_source_id;
   config.params.column_name = config.column_name;
   if ( !(config.callback instanceof Function)) {
      throw "editable source popup needs a callback!";
   }

   var filter_field = null;
   var grid = null;
   var ok_button = null;

   filter_field = new Ext.form.TextField({
      name: "filter",
      width: 265,
      enableKeyEvents: true,
      listeners: {
         keypress: {
            buffer: 350,
            scope: this,
            fn: function () {
               if (grid.getStore().baseParams.filter !== filter_field.getValue()) {
                  grid.getStore().baseParams.filter = filter_field.getValue();
                  grid.getStore().reload();
               }
            }
         }
      }
   });

   grid = new Ext.grid.GridPanel({
      region: "center",
      height: 300,
      border: false,
      loadMask: true,
      store: new Ext.data.JsonStore({
         url: "/data/load_grid",
         baseParams: config.params,
         root: "rows",
         fields: ["value"],
         autoLoad: true
      }),
      cm: new Ext.grid.ColumnModel([
         {dataIndex: "value", header: "Name"}
      ]),
      viewConfig: {
         forceFit: true
      },
      tbar: [
         "Search: ",
         " ",
         filter_field
      ],
      sm: new Ext.grid.RowSelectionModel({
         singleSelect:true,
         listeners: {
            selectionchange: function(sm) {
               if (sm.getSelected()) {
                  ok_button.enable();
               } else {
                  ok_button.disable();
               }
            }
         }

      })
   });

   var buttons = [];
   var popup = null;

   if(config.new_text) {
      buttons.push({
         text: 'New',
         handler: function() {
            popup.hide();
            Ext.Msg.prompt("New", config.new_text, function (button, text) {
               if (button === "ok") {
                  $(config.field_id).value = text;
                  $(config.field_id + "_display").innerHTML = text;
               }
            });
         }
      });
   }

   buttons.push({
      text: 'Cancel',
      handler: function(btn) {
         popup.hide();
      }
   });

   ok_button = new Ext.Button({
      text: 'Select',
      disabled: true,
      handler: function(btn) {
         var selected_row = grid.getSelectionModel().getSelected();
         config.callback(selected_row.get('value'));
         popup.hide();
      }
   });

   buttons.push(ok_button);

   popup = new ExtSfr.PopupPanel({
      title: config.title ? config.title : "Edit Value",
      items: grid,
      layout: "fit",
      width: 600,
      buttons: buttons
   });

   popup.show();
};


/*global Ext ExtSfr */
var EventProgramsComponent = {};

EventProgramsComponent.initialize_edit = function(container_div_id, config) {
   var event_id_field = ExtSfr.FormFactory.createComboBox({
      fieldLabel: 'Event',
      data_source_id: 'events',
      name: 'event_id_' + container_div_id,
      auto_load: true,
      anchor: '100%',
      value: config.event_id
   });
   
   var color_field = new Ext.form.TextField({
      fieldLabel: "Color for Day Bars",
      name: "color_" + container_div_id,
      value: config.color,
      anchor: "100%"
   });

   var panel = new Ext.Panel({
      layout: 'form',
      border: false,
      bodyStyle: 'padding: 5px;',
      labelWidth: 250,
      renderTo: "event_programs_panel_" + container_div_id,
      items: [event_id_field, color_field]
   });
};



/**
 * @author rroman
 */
var FaqsComponent = {};
FaqsComponent.init = function(container_div_id,filter) {
   var filter = new Ext.form.TriggerField({
      fieldLabel: "Filter",
      width: 250,
      name: 'faqs_' + container_div_id,
      readOnly: false,
      value: filter || "",
      onTriggerClick: function() {
         var frw = new FlexReportWindow('faq_questions', {
            title: "Select Questions",
            base_filter: 'status=Active public=yes',
            filter: filter.getValue(),
            callback: function(record) {
               filter.setValue(frw.getFilterString());
            }
         });
         frw.show();
      }
   });
   
   var panel = new Ext.Panel({
      layout: 'form',
      border: false,
      bodyStyle: 'padding: 5px;',
      renderTo: "faqs_" + container_div_id,
      items: filter
   }); 
};

FormComponent = {};
FormComponent.initialize_edit = function(container_div_id, config) {
   
   FormComponent.FieldPanel = Ext.extend(Ext.Panel, {
      constructor: function(field_config) {
         var label_field = new Ext.form.TextField({
            fieldLabel: "Field Label",
            value: field_config.label,
            name: 'field_labels_' + field_config.container_div_id + "[]"
         });
         var name_field = new Ext.form.TextField({
            fieldLabel: "Field Name",
            allowBlank: false,
            value: field_config.name,
            name: 'field_names_' + field_config.container_div_id + "[]"
         });
         var type_field = ExtSfr.FormFactory.createComboBox({
            store: [ ['text', 'Text field'],
                     ['multi', 'Multi select'],
                     ['select', 'Select']
                   ],
            fieldLabel: "Field Type",
            name: 'field_types_' + field_config.container_div_id + "[]",
            value: field_config.type,
            listeners: {
               select: function() {
                  var v = type_field.getValue();
                  if (v === 'multi' || v === 'select') {
                     select_panel.show();
                  } else {
                     select_panel.hide();
                  }
               }
            }
         });

         var rand = Math.random() * 100000;

         var select_mode = new Ext.form.Hidden({
            name: 'select_modes_' + field_config.container_div_id + "[]",
            value: field_config.select_mode
         })
      
         var ds_select = new Ext.form.Radio({
            boxLabel: "Data Source",
            hideLabel: true,
            name: 'select_sources_' + rand,
            checked: field_config.select_mode === 'data_source',
            listeners: {
               check: function(radio, checked) {
                  if (checked) {
                     data_source_panel.show();
                     options_list.hide();
                     select_mode.setValue('data_source');
                  }
               }
            }
         });
      
         var list_select = new Ext.form.Radio({
            boxLabel: "List of values",
            hideLabel: true,
            name: 'select_sources_' + rand,
            checked: field_config.select_mode === 'list',
            listeners: {
               check: function(radio, checked) {
                  if (checked) {
                     options_list.show();
                     data_source_panel.hide();
                     select_mode.setValue('list');
                  }
               }
            }
         });

         ////
         //// Stuff for configuring choices based on data sources

         var sources = [];
         for (var dsid in Data.source_cache) {
           var ds = Data.source_cache[dsid];
           //skip sources that need authorization
           if (ds.authorization_tag && !scup.authorizations[ds.authorization_tag])
              continue;
        
           sources.push({
              id: dsid,
              name: ds.name
           })
         }

         var data_source_config = new Ext.form.Hidden({
            name: 'data_source_configs_' + field_config.container_div_id + "[]",
            value: Ext.encode(field_config.data_source_config)
         });

         var data_source_id = null;
         if (field_config.data_source_config) {
            data_source_id = field_config.data_source_config.data_source_id;
         }
 
         var data_source_box = ExtSfr.FormFactory.createComboBox({
            store: new Ext.data.JsonStore({
               data: {sources: sources},
               root: 'sources',
               fields: ['id', 'name']
            }),
            displayField: 'name',
            valueField: 'id',
            fieldLabel: 'Data Source',
            value: data_source_id
         });

         var data_source_columns = ExtSfr.FormFactory.createComboBox({
            fieldLabel: 'Display Column',
            store: [],
            name: 'data_source_columns_' + field_config.container_div_id + "[]"
         });

         var populate_columns = function(ds_id) {
            var columns = [];
            if (Data.source_cache[ds_id]) {
               Data.source_cache[ds_id].columns.each(function(col) {
                  columns.push(col.name);
               });
            }
            data_source_columns.store.loadData(columns);
            data_source_columns.setValue("");
         }

         data_source_box.on('select', function(combo, record, index) {
            populate_columns(record.data.id);
            data_source_config.setValue(Ext.encode({data_source_id: record.data.id }));
            data_source_columns.enable();
            configure_source_button.enable();
         });

         if (data_source_id) {
            populate_columns(data_source_id);
            data_source_columns.setValue(field_config.data_source_column);
         }

         var configure_source_button = new Ext.Button({
            text: 'Sort and filter',
            disabled: !data_source_id,
            handler: function() {

               var config = Ext.decode(data_source_config.getValue());
               if (config == null || config.data_source_id != data_source_box.getValue()) {
                  //changed source, start fresh
                  config = {data_source_id: data_source_box.getValue()};
               }

               Data.sort_and_filter(config, function(dsc) {
                  data_source_config.setValue(Ext.encode(dsc))
               });
            }
         })

         var options_list = new ExtSfr.FieldWrapper({
            xtype: 'textarea',
            width: 300,
            hidden: field_config.select_mode !== 'list',
            fieldLabel: 'Options, one per line',
            name: 'list_of_options_' + field_config.container_div_id + "[]",
            value: field_config.list_of_options
         });
      
         var data_source_panel = new Ext.Panel({
            layout: 'form', 
            border: true,
            bodyStyle: 'padding: 5px;',
            labelWidth: 1,
            hideMode: 'offsets',
            hidden: field_config.select_mode !== 'data_source',
            items: [data_source_box, data_source_columns, data_source_config, configure_source_button]
         });


         /// The panel that shows up for multi/select

         var select_panel = new Ext.Panel({
            layout: 'form',
            hideMode: 'offsets',
            hidden: !(field_config.type === 'select' || field_config.type === 'multi'),
            labelWidth: 1,
            border: false,
            items: [
               {
                  xtype: 'label',
                  text: 'Choices come from: '
               },
               select_mode,
               ds_select, list_select, options_list, data_source_panel]

         })

         var config = {
            layout: 'form',
            labelAlign: 'top',
            bodyStyle: 'padding: 5px;',
            frame: false,
            tbar: ['->', {
               iconCls: 'closeIcon',
               text: "Delete",
               handler: function() {
                  this.ownerCt.remove(this, true);
               },
               scope: this
            }],
            border: true,
            items: [
               type_field,
               label_field,
               name_field,
               select_panel
            ]
         };

         FormComponent.FieldPanel.superclass.constructor.apply(this, [config]);
      }

   });

   var page_picker = new ExtSfr.FieldWrapper(ExtSfr.FormFactory.createComboBox({
      data_source_id: 'cms_pages',
      auto_load: true,
      fieldLabel: "Submit URL",
      name: 'page_id_' + container_div_id,
      value: config.page_id,
      base_filter: "manager_ids=" + scup.current_user.id
   }));
   
   var url_field = new ExtSfr.FieldWrapper({
      xtype: 'textfield',
      name: "url_" + container_div_id,
      fieldLabel: "Submit URL",
      value: config.url
   });
   
   var page_checkbox = new Ext.form.Checkbox({
      name: "use_page_" + container_div_id,
      hideLabel: true, 
      boxLabel: "Submit to a CMS Page?",
      checked: !config.url, //check if there is a page set or if component is new
      listeners: {
         check: function() {
            if(page_checkbox.checked) {
               url_field.hide();
               page_picker.show();  
            } else {
               url_field.show();
               page_picker.hide();
            }
         }
      }
   });
   
   var search_form_panel = new Ext.Panel({
      layout: 'form',
      border: false,
      hidden: config.form_type === 'edit_form',
      hideMode: 'offsets',
      items: [
         page_checkbox, 
         page_picker,
         url_field,
         {
          xtype: 'textfield',
          fieldLabel: 'Button label',
          name: 'submit_text_' + container_div_id,
          value: config.submit_text
        }
      ],
      buttons: [{
         text: "Add another field", 
         handler: function() {
            panel.add(new FormComponent.FieldPanel({container_div_id: container_div_id}));
            panel.doLayout();
         }
      }]
   });

   if (config.url) {
      page_picker.hide();
      url_field.show();
   } else {
      page_picker.show();
      url_field.hide();
   }

   if (config.fields.length === 0) {
      search_form_panel.add(new FormComponent.FieldPanel({container_div_id: container_div_id}));
   }else {
      config.fields.each(function(fc) {
         fc.container_div_id = container_div_id;
         search_form_panel.add(new FormComponent.FieldPanel(fc));
      });
   }

   var panel = new Ext.Panel({
      layout: 'form',
      border: false,
      bodyStyle: 'padding: 5px;',
      renderTo: "form_panel_" + container_div_id,
      items: [
         search_form_panel
      ]
   });

   panel.doLayout();
};



/*global GoogleSearchComponent GSearch GSearchControl google Sfr */

// the cse class encapsulates a left and right search control
// both controls are driven by a shared search form
var GoogleSearchComponent = {};


GoogleSearchComponent.searcher = function(config) {
   this.config = config;
   var sFormDiv = document.getElementById("searchForm");
   var leftScDiv = document.getElementById("leftSearchControl");

   // create a left, right search control
   // create a custom search form
   this.leftControl = new google.search.SearchControl();
   
   if (this.config.show_search_box) {
      this.searchForm = new google.search.SearchForm(false, sFormDiv);
      // bind clear and submit functions
      this.searchForm.setOnSubmitCallback(this, GoogleSearchComponent.searcher.prototype.onSubmit);
   }


   // set up for large result sets
   this.leftControl.setResultSetSize(GSearch.LARGE_RESULTSET);
   this.leftControl.setLinkTarget(GSearch.LINK_TARGET_SELF);

   var searcher;
   var options;

   // configure left control
   // bsamson scup testing cse
   //var cseId = "013409294529337139102:-wd45hpk01u"

   //amazon.com
   //cseId = "000455696194071821846:reviews";
   if (config.search_mode === 'web') {
      searcher = new google.search.WebSearch();
      searcher.setUserDefinedLabel("Search Results");
      options = new google.search.SearcherOptions();
      options.setExpandMode(GSearchControl.EXPAND_MODE_OPEN);
      this.leftControl.addSearcher(searcher, options);
   } else if (config.search_mode === 'site') {
      searcher = new google.search.WebSearch();
      searcher.setUserDefinedLabel("Search Results");
      options = new google.search.SearcherOptions();
      searcher.setSiteRestriction(config.site);
      options.setExpandMode(GSearchControl.EXPAND_MODE_OPEN);
      this.leftControl.addSearcher(searcher, options);
   } else if (config.search_mode === 'custom') {

      var cseId = config.cse_key;
      searcher = new google.search.WebSearch();
      searcher.setUserDefinedLabel("Search Results");
      options = new google.search.SearcherOptions();
      searcher.setSiteRestriction(cseId);
      options.setExpandMode(GSearchControl.EXPAND_MODE_OPEN);
      this.leftControl.addSearcher(searcher, options);

      //Refinement tabs, I might need to automate this
      if (config.show_refinements && config.cse_refinements) {
         //set up the right control, which should be drawn by the view
         var rightScDiv = document.getElementById("rightSearchControl");
         this.rightControl = new google.search.SearchControl();
         this.rightControl.setResultSetSize(GSearch.LARGE_RESULTSET);
         this.rightControl.setLinkTarget(GSearch.LINK_TARGET_SELF);

         config.cse_refinements.each(function(ref) {
            searcher = new google.search.WebSearch();
            options = new google.search.SearcherOptions();
            searcher.setSiteRestriction(cseId, ref);
            searcher.setUserDefinedLabel(ref);
            this.rightControl.addSearcher(searcher, options);
         }, this);

         // draw the left and right controls
         // the right control is drawn in tabbed mode
         var drawOptions = new google.search.DrawOptions();
         drawOptions.setDrawMode(GSearchControl.DRAW_MODE_TABBED);
         this.rightControl.draw(rightScDiv, drawOptions);
      }
   }

   this.leftControl.draw(leftScDiv);
   var qs = new Sfr.QueryString();

   if (this.config.show_search_box) {
      this.searchForm.execute(qs.get('q'));
   } else {
      var q = this.getSearchParams(qs.get('q'));
      this.leftControl.execute(q);
      if (this.rightControl) {
         this.rightControl.execute(q);
      }
   }

   
};

// when the form fires a submit, grab its
// value and call the left and right control
GoogleSearchComponent.searcher.prototype.onSubmit = function(form) {
   var q = this.getSearchParams(form.input.value);
   if (q && q!== "") {
      this.leftControl.execute(q);
      if (this.rightControl) {
        this.rightControl.execute(q);
      }
   }
   return false;
};

// when the form fires a clear, call the left and right control
GoogleSearchComponent.searcher.prototype.onClear = function(form) {
   this.leftControl.clearAllResults();
   if (this.rightControl) {
     this.rightControl.clearAllResults();
   }
   form.input.value = "";
   return false;
};

GoogleSearchComponent.searcher.prototype.getSearchParams = function(q) {
   if (!q) {
      q = "";
   }
   if (this.config.keywords) {
      q = q + ' ' + this.config.keywords;
   }

   if (this.config.url_pattern) {
      q = q + " inurl:" + this.config.url_pattern;
   }

   return q;
};

GoogleSearchComponent.begin_search = function(config) {
   if (!google.search) {
      google.load('search', '1', {'nocss': true});
      google.setOnLoadCallback(function() {
         (new GoogleSearchComponent.searcher(config));
      }, true);
   } else {
      //not the first load
      (new GoogleSearchComponent.searcher(config));
   }
};


/*global scup, Data, ExtSfr, Ext, Form, Ajax, Element, FlexReportWindow, Event $ */

var ImageMapComponent = {};

// hash of container_div_ids to configs
ImageMapComponent.config_map = {};

// hash of container_div_ids to region data fields
ImageMapComponent.regions_data_field_map = {};

// hash of container_div_ids to hash of record id to message
ImageMapComponent.region_messages = {};

ImageMapComponent.initialize_edit = function(container_div_id, config) {

   // tuck the config away for future reference
   ImageMapComponent.config_map[container_div_id] = config;
   
   var auto_assign_column_field = null; // referred to throughout
   
   var asset_id_field = new ExtSfr.MiniFlexCombo({
      fieldLabel: "Background Image",
      data_source_id: "cms_assets",
      name: "asset_id_" + container_div_id,
      valueField: "id",
      displayField: "title",
      value: config.asset_id
   });
   
   asset_id_field.on("select", function (record) {
      config.asset_id = record.get("id");
      ImageMapComponent.render_edit_region(container_div_id, config);
   });
   
   var sources = [];
   // build a store from the data source cache
   for (var dsid in Data.source_cache) {
      if (Data.source_cache.hasOwnProperty(dsid)) {
         var ds = Data.source_cache[dsid];
         if (ds.id !== ds.name) { // we don't want named sources
            sources.push({
               id: dsid,
               name: ds.name
            });
         }
      }
   }
   
   sources = sources.sort(function(a,b) {
      if (a.name < b.name) {
         return -1;
      }
      if (a.name > b.name) {
         return 1;
      }
      return 0;
   });

   var data_source_field = ExtSfr.FormFactory.createComboBox({
      store: new Ext.data.JsonStore({
         data: {sources: sources},
         root: 'sources',
         fields: ['id', 'name']
      }),
      name: 'data_source_id_' + container_div_id,
      displayField: 'name',
      valueField: 'id',
      fieldLabel: 'Data Source',
      value: config.data_source_id,
      listeners: {
         select: function () {
            config.data_source_id = data_source_field.getValue();
            auto_assign_column_field.getStore().loadData(
               Data.source_cache[config.data_source_id]
            );
            auto_assign_column_field.setValue("");
         }
      }
   });
   
   var template_field = new Ext.form.TextArea({
      name: "template_" + container_div_id,
      fieldLabel: "Flyover Template",
      anchor: "100%",
      height: 50,
      value: config.template
   });
   
   var no_record_template_field = new Ext.form.TextArea({
      name: "no_record_template_" + container_div_id,
      fieldLabel: "No-Record Template",
      anchor: "100%",
      height: 50,
      value: config.no_record_template
   });
   
   var regions_data_field = new Ext.form.Hidden({
      name: "regions_" + container_div_id,
      value: Ext.encode(config.regions)
   });
   ImageMapComponent.regions_data_field_map[container_div_id] = regions_data_field;
   
   var regions_field = new Ext.form.TriggerField({
      fieldLabel: "Regions",
      name: "regions_display",
      triggerClass: "import-trigger",
      value: (config.regions.length > 0) ? (config.regions.length + " regions defined") : "",
      emptyText: "Click to import",
      readOnly: true,
      listeners: {
         render: function (combo) {
            regions_field.getEl().on('click', regions_field.onTriggerClick, regions_field);
         }
      },
      onTriggerClick: function() {
         var show_window = function() {
            var edit_form = new Ext.form.FormPanel({
               border: false,
               bodyStyle: "padding: 8px;",
               url: '/cms/image_map_component/import_html',
               method: 'POST',
               labelAlign: "top",
               fileUpload: true,
               items: [new Ext.form.Field({
                  fieldLabel: 'Select an HTML File',
                  name: 'file',
                  inputType: 'file'
               })]
            });
            
            var win = new Ext.Window({
               modal: true,
               title: "Import HTML Image Map",
               items: edit_form,
               buttons: [{
                  text: "Cancel",
                  handler: function () {
                     win.close();
                  }
               },{
                  text: "Import",
                  handler: function () {
                     Ext.Msg.wait("Processing HTML file...", "Please Wait");
                     edit_form.getForm().submit({
                        success: function (theForm, action) {
                           var data = Ext.decode(action.response.responseText);
                           config.regions = data.regions;
                           regions_data_field.setValue(Ext.encode(config.regions));
                           regions_field.setValue(config.regions.length + " regions");
                           ImageMapComponent.render_edit_region(container_div_id, config);
                           Ext.Msg.hide();
                           win.close();
                        },
                        failure: scup.handle_failure
                     });
                  }
               }]
            });
            
            win.show();
         };
         
         if (config.regions.length > 0) {
            Ext.Msg.confirm(
               "Import HTML",
               "Are you sure you want to import again? All existing regions will be deleted.", 
               function(btn) {
                  if (btn === "yes") {
                     show_window();
                  }
               }
            );
         }
         else {
            show_window();
         }
      }
   });
   
   var manual_mode_radio = ExtSfr.FormFactory.createRadio({
      fieldLabel: "Manually assign records to regions on the map",
      name: "assign_mode_" + container_div_id,
      inputValue: "manual",
      checked: !config.auto_assign_column
   });
   
   var automatic_mode_radio = ExtSfr.FormFactory.createRadio({
      fieldLabel: "Automatically assign records to regions on the map",
      name: "assign_mode_" + container_div_id,
      inputValue: "automatic",
      checked: !!config.auto_assign_column,
      listeners: {
         check: function(rb, checked) {
            if (checked) {
               auto_assign_column_field.setValue(auto_assign_column_field.getStore().getAt(0).get("name"));
            }
         }
      }
   });
   automatic_mode_radio.on("check", function () {
      if (automatic_mode_radio.getValue()) {
         auto_assign_column_field.enable();
         config.assign_mode = "automatic";
      }
      else {
         auto_assign_column_field.disable();
         config.assign_mode = "manual";
      }
   });
   
   auto_assign_column_field = ExtSfr.FormFactory.createComboBox({
      fieldLabel: 'Match "href" to Column',
      name: "auto_assign_column_" + container_div_id,
      value: config.auto_assign_column,
      valueField: "name",
      store: new Ext.data.JsonStore({
         root: "columns",
         fields: ["name"],
         data: Data.source_cache[config.data_source_id] || {columns: []}
      }),
      disabled: !config.auto_assign_column
   });
   
   var config_panel = new Ext.Panel({
      layout: 'form',
      border: false,
      labelAlign: "top",
      bodyStyle: 'padding: 5px;',
      height: 330,
      autoScroll: false,
      hideMode: "offsets",
      items: [
         regions_data_field,
         ExtSfr.side_by_side_fields([asset_id_field, data_source_field, regions_field]),
         manual_mode_radio,
         automatic_mode_radio,
         {
            border: false,
            layout: "form",
            labelAlign: "top",
            bodyStyle: "padding: 0 0 10px 30px",
            items: auto_assign_column_field
         },
         template_field,
         no_record_template_field
      ]
   });
   
   var preview_panel = new Ext.Panel({
      border: false,
      contentEl: "image_map_preview_" + container_div_id
   });

   preview_panel.on("afterLayout", function () {
      preview_panel.setHeight(
         Ext.Element.get("image_map_preview_" + container_div_id).getHeight()
      );
   });
   
   var panel = new Ext.Panel({
      border: false,
      layout: "card",
      activeItem: 0,
      deferredRender: true,
      layoutOnCardChange: true,
      hideMode: "offsets",
      renderTo: "form_panel_" + container_div_id,
      items: [
         preview_panel,
         config_panel
      ],
      tbar: [{
         text: "Configure",
         enableToggle: true,
         iconCls: "wrenchIcon",
         handler: function (button) {
            if (button.pressed) {
               panel.getLayout().setActiveItem(1);
               config_panel.doLayout();
            }
            else {
               panel.getLayout().setActiveItem(0);
               preview_panel.setHeight(
                  Ext.Element.get("image_map_preview_" + container_div_id).getHeight()
               );
            }
         }
      }]
   });

   panel.doLayout();
};

ImageMapComponent.render_edit_region = function(container_div_id, config) {
   // build the area tags
   var areas = [];
   var markers = [];
   
   if (config.assign_mode === "manual") {
      for (var i = 0; i < config.regions.length; i++) {
         var coords = "" + config.regions[i].left + "," + 
            config.regions[i].top + "," + 
            (config.regions[i].left + config.regions[i].width) + "," + 
            (config.regions[i].top + config.regions[i].height);
         areas.push({
            tag: "area",
            shape: "rect",
            coords: "" + coords
         });
         
         var marker_class = "image-map-marker region_" + i;
         if (config.regions[i].record_id) {
            marker_class += " selected";
         }
         markers.push({
            tag: "div",
            cls: marker_class,
            style: "position: absolute; top: " + config.regions[i].top + "px; " +
                   "left: " + config.regions[i].left + "px; " +
                   "width: " + config.regions[i].width + "px; " + 
                   "height: " + config.regions[i].height + "px;",
            onclick: "ImageMapComponent.click_region('" + container_div_id + "', " + i + ");",
            children: {
               tag: "div"
            }
         });
      }
   }
   
   // build the html spec
   var spec = [{
      tag: "img",
      src: "/asset/" + config.asset_id,
      usemap: "#image_map_" + container_div_id
   },{
      tag: "map",
      name: "image_map_" + container_div_id,
      children: areas
   },
   markers];
   
   Ext.DomHelper.overwrite("image_map_preview_" + container_div_id, spec);
};

ImageMapComponent.click_region = function(container_div_id, region_idx) {
   var config = ImageMapComponent.config_map[container_div_id];
   var regions_data_field = ImageMapComponent.regions_data_field_map[container_div_id];
   if (!config.data_source_id) {
      Ext.Msg.alert("Not Configured", "You have not selected a data source for this component. Click Configure, select a data source, then try again.");
   }
   else {
      var id = config.regions[region_idx].record_id;
      var frw = new FlexReportWindow(config.data_source_id, {
         title: "Select Record",
         auto_load: !!id,
         filter: id ? "id=" + id : "",
         left_button: {
            text: "Clear Current Choice",
            disabled: !config.regions[region_idx].record_id,
            handler: function () {
               frw.close();
               frw.callback(null);
            }
         },
         callback: function(record) {
            var marker = Ext.Element.get("image_map_preview_" + container_div_id).first(".region_" + region_idx);
            if (record) {
               config.regions[region_idx].record_id = record.get("id");
               marker.addClass("selected");
            }
            else {
               config.regions[region_idx].record_id = null;
               marker.removeClass("selected");
            }
            regions_data_field.setValue(Ext.encode(config.regions));
         }
      });
      frw.show();
   }
};

ImageMapComponent.pop = function (e, container_div_id, record_id) {
   if (ImageMapComponent.unpop_timer) {
      clearTimeout(ImageMapComponent.unpop_timer);
      ImageMapComponent.unpop_timer = null;
   }
   var el = $("image_map_pop_" + container_div_id);
   if (!el) {
      el = document.createElement("div");
      el.id = "image_map_pop_" + container_div_id;
      el.className = "image-map-pop";
      el.style.display = "none";
      el.onmouseover = function() {
         ImageMapComponent.over_pop = true;
      };
      el.onmouseout = function() {
         ImageMapComponent.over_pop = false;
         ImageMapComponent.unpop(container_div_id);
      };
      document.body.appendChild(el);
   }
   var message = ImageMapComponent.region_messages[container_div_id][record_id];
   if (message) {
      el.innerHTML=message;
      el.show();
      el.style.left = (Event.pointerX(e) + 5) + "px";
      el.style.top = (Event.pointerY(e)) + "px"; 
   }
};

ImageMapComponent.unpop_timer = null;
ImageMapComponent.unpop = function (container_div_id) {
   if (ImageMapComponent.unpop_timer) {
      clearTimeout(ImageMapComponent.unpop_timer);
      ImageMapComponent.unpop_timer = null;
   }
   ImageMapComponent.unpop_timer = setTimeout(function() {
      ImageMapComponent.unpop_impl(container_div_id);
   }, 300);
};

ImageMapComponent.unpop_impl = function (container_div_id) {
   // don't hide if they are over the popup
   if (ImageMapComponent.over_pop) {
      return;
   }
   $("image_map_pop_" + container_div_id).hide();
   ImageMapComponent.unpop_timer = null;
};

/* 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
ViewSharedComponent = {
   set_configuration: function(uniqueId, config) {     
      $('shared_config_' + uniqueId).value = Ext.encode(config);
   }
};

ViewSharedComponent.shared_configs = {};

ViewSharedComponent.shared_options_handlers = {
  data_set: function(config, callback) {
     Data.sort_and_filter(config.data_source_config, function(new_config) {
        callback({data_source_config: new_config});
     });
  }   
};

ViewSharedComponent.initialize_edit = function(container_div_id, shared_component, current_config) {
   var descLabel = new Ext.form.Label({
      fieldLabel: 'Description',
      text: "Select a component to see a description",
      width: '100%'
   });
   
   var shared_config_field = new Ext.form.Hidden({
      name: 'shared_config_' + container_div_id,
      id: 'shared_config_' + container_div_id
   });

   var configButton = new Ext.Button({
      text: "Options",
      disabled: !shared_component.allow_override,
      sfr_shared_component: shared_component,
      sfr_current_config: current_config,
      handler: function() {
         var sc = configButton.sfr_shared_component.edit_version;
         var f = ViewSharedComponent.shared_options_handlers[sc.component_name];
         f(configButton.sfr_current_config, function(new_config) {
            configButton.sfr_current_config = new_config;
            ViewSharedComponent.set_configuration(container_div_id, new_config);
         });
      }
   });

   var scid_field = new Ext.form.Hidden({
      name: 'shared_component_id_' + container_div_id,
      value: shared_component.id
   });
   
   var combo = new Ext.form.TriggerField({
      fieldLabel: "Shared component",
      editable: false,
      width: 300,
      value: shared_component.name,
      onTriggerClick: function() {
         var frw = new FlexReportWindow('cms_shared_components', {
            title: "Select a shared component",
            callback: function(record) {
               //get the full shared_component 
               frw.flex_report_panel.hydrate(record.data.id, function(new_shared_component) {
                  descLabel.setText(new_shared_component.description);
                  combo.setValue(new_shared_component.name);
                  scid_field.setValue(new_shared_component.id);
                  //clear the shared_config because its a totally different SC now
                  if (new_shared_component.allow_override){
                     configButton.sfr_shared_component = new_shared_component;
                     configButton.sfr_current_config = new_shared_component.edit_version.shared_config;
                     ViewSharedComponent.set_configuration(container_div_id, configButton.sfr_current_config);
                     configButton.enable();
                  } else {
                     configButton.disable();
                  }
               });
               
            }
         });
         frw.show();
      }
   });
   
   if (shared_component){
      descLabel.setText(shared_component.description);
   }
   
   var panel = new Ext.Panel({
      layout: 'form',
      border: false,
      bodyStyle: 'padding: 5px;',
      labelWidth: 250,
      renderTo: "sc_panel_" + container_div_id,
      items: [scid_field, shared_config_field, combo,
         {
            xtype: 'panel',
            border: false,
            html: "<div>Description of component:</div> "
         }, 
         descLabel],
      buttons: [
         configButton
      ]
   });
   
 
};


