/*global Ext, Math, escape*/

Ext.ns('Ext.ux.form');

Ext.ux.form.CompanyProfileField = Ext.extend(Ext.ux.form.BaseField, {
  /**
    * @cfg {String/Object} defaultAutoCreate DomHelper element spec
    * Let superclass to create hidden field instead of textbox. Hidden will be submittend to server
    */
  defaultAutoCreate: {tag: 'input', type: 'hidden'},
          
  name: '',
  
  allowBlank: true,

  companyServiceMethod: 'SearchCompany',                               // Name of the service method to fetch company list

  companyProfileServiceMethod: 'FetchCompanyProfiles',                 // Name of the service method to fetch company profiles

  fetchProfileParam: 'RecordId',                                       // Search parameter  

  companyProfileFieldId: '',                                           // Name of the company profile combo

  companyProfileFieldName: '',                                         // Name of the company profile combo

  companyProfileFieldWidth: 180,                                       // Width of the company profile combo

  companyProfileFieldDisplay: 'Name',                                  // Display field name of the company profile combo

  companyProfileFieldValue: 'RecordId',                                // Value field name of the company profile combo

  companyProfileData: [],                                              // company profile data array for company profile combo                    
  companyData: [],

  companyGridWindowTitle: 'Locate Company Profile',

  companyGridWindowWidth: 300,

  companyGridWindowHeight: 250,
  
  profileNameColWidth: 272,

  companyEmptyText: 'Select/Type Company',
  
  removeButtonText: 'Remove Profile',
  
  // {{{
  /**
    * private
    * creates company profile combo and related fields
    */
  initComponent: function () {
    //local variables 
    var companyProfileFieldConfig, removeButtonConfig;
    
    // call parent initComponent
    Ext.form.ComboBox.superclass.initComponent.call(this);
    Ext.form.TextField.superclass.initComponent.call(this);
         
    //forming field name & ids
    this.fieldName = (this.name !== '') ? this.name: this.id;
    this.errorHolderId = this.id + '.ERR';
    
    //Combo Event Override
    Ext.override(Ext.form.ComboBox, {
      initEvents : function () {
        Ext.form.ComboBox.superclass.initEvents.call(this);
	      this.queryDelay = Math.max(this.queryDelay || 10, this.mode === 'local' ? 10 : 250);
	      this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
	      if (this.typeAhead) {
	        this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
	      }
      }/*,
      onKeyUp : function (e) {
        if (this.editable !== false && !e.isSpecialKey()) {
          this.lastKey = e.getKey();
          this.dqTask.delay(this.queryDelay);
        }
	      Ext.form.ComboBox.superclass.onKeyUp.call(this, e);
      }*/
    });
      
    //company profile combo
    this.companyProfileData = [];
    this.companyProfileStoreConfig = {
      fields: [this.companyProfileFieldValue, this.companyProfileFieldDisplay],
      data: this.companyProfileData
    };
                       
    this.companyProfileStore = new Ext.data.SimpleStore(this.companyProfileStoreConfig);
          
    companyProfileFieldConfig = Ext.apply({}, {
      //id: this.id + '_company_profile',
      id: 'testing',
      name: (this.companyProfileFieldName !== '') ? this.companyProfileFieldName : this.id + '_company_profile',
      allowBlank: this.allowBlank,
      mode: 'local',
      store: this.companyProfileStore,
      displayField: this.companyProfileFieldDisplay,
      valueField: this.companyProfileFieldValue,
      width: this.companyProfileFieldWidth,
      emptyText: this.companyEmptyText,
      enableKeyEvents: true,
      triggerAction: 'all',
      editable: true,
      listeners: {
        select: {scope: this, fn: this.onSelect},
        keyup: {
          scope: this, 
          fn: function (combo) {
            var prevSearchStr = '';
            if (this.searchText !== undefined)
            {
              prevSearchStr = this.searchText;
            }
            if (combo.getRawValue().search(/\S/) !== -1 && prevSearchStr !== combo.getRawValue())
            {
              this.searchText = combo.getRawValue();
              combo.ownerCt.updateHidden();
              try{ this.delayObj.cancel(); } catch(ex){}
              this.delayObj = new Ext.util.DelayedTask(function () {
                combo.ownerCt.loadCompanyStore();	
              });
              this.delayObj.delay(500);
            }  
          }            
        },
        blur: {
          scope: this,
          fn: function (combo) {
            var isMatched, i;
            isMatched = false;
            for (i = 0; i < this.companyProfileData.length; i = i + 1)
            {
              if (combo.getRawValue() === this.companyProfileData[i][1])
              {
                isMatched = true;
                break;
              }
            }
            if (!isMatched)
            {
              combo.setRawValue(combo.ownerCt.companyEmptyText);
            }
          }
        }
      }
    }, this.companyProfileFieldConfig);
    this.companyProfileField = new Ext.form.ComboBox(companyProfileFieldConfig);
    this.companyProfileField.ownerCt = this;
    
    
    // The remove person button
    removeButtonConfig = Ext.apply({}, {
      id: this.id + '_remove-button',
      name: this.id + '_remove-button',
      text: this.removeButtonText,
      listeners: {
        click: {scope: this, fn: this.removeSelectedProfile}
      }
    }, this.removeButtonConfig);
    
    this.removeButtonField = new Ext.Button(removeButtonConfig);
    
  }, // eo initcomponent
  // }}}
  // {{{
  /**
    * private
    * Renders the fields 
    */
  onRender: function (ct, position) {
    //local variables
    var domHelperObj;
    // don't run more than once
    if (this.isRendered) {
      return;
    }
    // render underlying hidden field
    Ext.form.TextField.superclass.onRender.call(this, ct, position);

    this.ct = ct;
    this.position = position;

    // create bounding table
    domHelperObj = Ext.DomHelper.append(ct, {
      tag: 'table', 
      children: [{
        tag: 'tr', 
        children: [
          {tag: 'td', id: this.id + '_added-company-profile', style: 'padding-right:4px;display:none'},
          {tag: 'td', style: 'padding-right:4px', cls: this.id + '_ux-company-profile-field'},
          {tag: 'td', id: this.id + '_remove-profile', cls: this.id + '_ux-remove-profile-btn'},
          {tag: 'td', id: this.id + '_loading-symbol', style: 'padding-right:4px', html: ''}
        ]
      }, {
        tag: 'tr', 
        children: [{tag: 'td', colspan: 4,  id: this.errorHolderId, cls: 'field-error',  style: 'display:none', html: ''}]
      }]
    }, true);
    // render company profile combo
    this.companyProfileField.render(domHelperObj.child('td.' + this.id + '_ux-company-profile-field'));
    this.removeButtonField.render(domHelperObj.child('td.' + this.id + '_ux-remove-profile-btn'));
    this.removeButtonField.hide();

    // setup name for submit
    this.el.dom.name = this.fieldName;

    // we're rendered flag
    this.isRendered = true;

    //update the underlying hidden field
    this.updateHidden();

  }, // eo onRender
  // }}}
  // {{{
  /**
    * private
    * To Updates the underlying hidden field value
  */
  updateHidden: function () {
    if (this.isRendered === true && this.companyProfileName !== undefined) {
      this.el.dom.value = this.companyProfileName;
    }
  }, // eo function updateHidden
  // }}}
  // {{{
  /**
    * private
    * function to take necessary action onchange of client combo
    */
  onSelect: function () {
    this.companyProfileField.setRawValue(this.companyProfileField.getRawValue().replace(/&amp;/, '&'));
    this.updateHidden();
    this.showCompanyProfileWindow();
  }, // eo function onSelect  
  // }}}  
  // {{{
  /**
    * private
    * function to display the loading image 
    */
  displayLoadingImage: function () {
    Ext.get(this.id + '_loading-symbol').dom.innerHTML = '<img src="' + this.loadingImage + '" border="0" align="middle" alt="">';
  },// eo function displayLoadingImage
  //}}}
  //{{{
  /**
    * private
    * function to load company profile store with fetched data 
    */
  loadCompanyStore: function () {
    this.displayLoadingImage();
    this.ajaxRequest({
      url: this.http + this.serverName + '/' + this.applicationName + '/' + this.handlerName + '/' + this.companyServiceMethod,
      params: {
        'strSearch': escape(this.searchText)
      },
      method: 'post',
      success: function (result, request) {
        if (request.params.strSearch === request.ownerCt.searchText)
        {
          request.ownerCt.hideLoadingImage();
          request.ownerCt.companyProfileString = result.responseText;
          request.ownerCt.populateCompanyProfileData();
        }  
      },
      failure: function (result, request) {
        if (request.params.strSearch === request.ownerCt.searchText)
        {
          request.ownerCt.hideLoadingImage();
          Ext.Msg.alert("Error", "Couldn't Fetch Companies!");
        }  
      }
    });
  },
  //}}}
  //{{{
  /**
    * private
    * function to populate company profile` data to the client combo 
    */
  populateCompanyProfileData: function () {
    var searchText = this.companyProfileField.getRawValue();
    this.processCompanyProfileData();       // To process the company profile data fetched via web service
    this.companyProfileField.reset();
    this.companyProfileField.setRawValue(searchText); 
    this.companyProfileStore.removeAll();
    this.companyProfileStore.loadData(this.companyProfileData); // To load the company profile  combo with fetched data
    this.updateHidden(); // to update underlying hidden field
  },
  //}}}
  //{{{
  /**
    * private
    * function to process company profile data in array format 
    */
  processCompanyProfileData: function () {
    var tmpArray, i, companyRow; 
    this.companyProfileData = [];
    tmpArray = [];
    tmpArray = this.jsonDecoder(this.companyProfileString);
    for (i = 0; i < tmpArray.length; i = i + 1) {
      companyRow = Ext.util.JSON.decode(tmpArray[i]);
      if (companyRow.ClientName !== undefined && companyRow.ClientName.search(/\S/) !== -1)
      {
        this.companyProfileData[this.companyProfileData.length] = [companyRow.ClientId, companyRow.ClientName];
      }
    }
  },
  //}}}
  // {{{
  /**
    * private
    * function to show the company profiles in a grid
    */
  showCompanyProfileWindow: function () {
    //local variables
    this.profileData = [];
    this.companyProfileGridStore = new Ext.data.Store({
      ownerCt: this,
      data: this.profileData,
      reader: new Ext.data.ArrayReader({ id: 'id' }, ['id', 'name'])
    });

    this.companyProfileGrid = new Ext.grid.GridPanel({
      region: 'center',
      autoScroll: true,
      frame: true,
      width: this.companyGridWidth,
      store: this.companyProfileGridStore,
      columns: [{header: "Name", dataIndex: 'name', width: this.profileNameColWidth}],
      listeners: {
        cellclick: {scope: this, fn: this.updateCompanyProfile}
      }
    });
            
    this.profileResultWindow = new Ext.Window({
      title: this.companyGridWindowTitle,
      closable: true,
      closeAction: 'hide',
      width: this.companyGridWindowWidth,
      height: this.companyGridWindowHeight,
      border: false,
      plain: true,
      layout: 'border',
      modal: true,
      items: [this.companyProfileGrid],
      buttons: [{
        text: 'Close',
        listeners: { 
          click: {
            scope: this,
            fn: function () {
              this.profileResultWindow.hide();
            }
          }    
        }
      }]
    });
        
    this.profileResultWindow.show(this);
    this.loadProfileStore();
  },
  //}}}
  // {{{
  /**
    * private
    * function to load company store with the fetched companies 
    */
  loadProfileStore: function () {
    //local variables
    this.enableBodyMask();
    this.ajaxRequest({
      url: this.http + this.serverName + '/' + this.applicationName + '/' + this.handlerName + '/' + this.companyProfileServiceMethod + '?' + this.fetchProfileParam + '=' + this.companyProfileField.getValue() + '&TypeId=1',
      success: function (result, request) {
        request.ownerCt.profileString = result.responseText;
        if (request.ownerCt.profileString !== '[]') {
          request.ownerCt.populateProfileData();
          request.ownerCt.disableBodyMask();
        }
        else
        {
          Ext.Msg.alert("Error", "No Record Found!");
          request.ownerCt.disableBodyMask();
        }
      },
      failure: function (result, request) {
        Ext.Msg.alert("Error", "No Record Found!");
        request.ownerCt.disableBodyMask();
      }
    });
  },
  //}}}
  // {{{
  /**
    * private
    * function to populate company profile data to the grid 
    */
  populateProfileData: function () {
    this.processProfileData();       // To process the company data fetched via web service
    this.companyProfileGridStore.removeAll();
    this.companyProfileGridStore.loadData(this.profileData); // To load te company grid store with fetched data
  },
  //}}}
  // {{{
  /**
    * private
    * function to process company profile data in array format 
    */
  processProfileData: function () {
    var tempArray, ccount, row;
    this.profileData = [];
    tempArray = [];
    tempArray = this.jsonDecoder(this.profileString);
    for (ccount = 0; ccount < tempArray.length; ccount = ccount + 1) {
      row = Ext.util.JSON.decode(tempArray[ccount]);
      this.profileData[ccount] = [row.RecordId, row.Name];
    }
  },
   //}}}
   // {{{
   /**
    * private
    * This is to update company profile combo as records are clicked in the company profile grid 
    */
  updateCompanyProfile: function (grid, rowIndex, colIndex, e) {
    //local variables
    var record, companyId;
    record = grid.getStore().getAt(rowIndex);
    companyId = record.data.id;
    this.companyProfileName = record.data.name;
    Ext.get(this.id + "_added-company-profile").dom.innerHTML = this.companyProfileName;
    Ext.get(this.id + "_added-company-profile").dom.style.display = '';
    this.updateHidden();
    this.removeButtonField.show();
    this.profileResultWindow.hide();
  },//
  //}}}
  // {{{
  /**
    * private
    * To remove the selected profile informations
    */
  removeSelectedProfile: function () {
    this.companyProfileField.setValue(this.companyEmptyText);
    Ext.get(this.id + '_added-company-profile').dom.innerHTML = '';
    Ext.get(this.id + '_added-company-profile').dom.style.display = 'none';
    this.companyProfileName = '';
    this.updateHidden();
    this.removeButtonField.hide();
  }, //eo removePerson
  //}}}
  // {{{
  /**
    * private
    * function to validate the component
    */
  isValid: function () {
    var isValid = true;
    if (!this.allowBlank)
	{
      if (this.companyProfileField.isValid())
      {
        isValid = true;
      }
      else
      {
        isValid = false;
      }
    }
    return isValid;
  }//eo function isValid
});

// register xtype
Ext.reg('xcompanyprofile', Ext.ux.form.CompanyProfileField);


