﻿Type.registerNamespace('ATI.Ajax.Controls.AutoComplete');

var ATTR_NAME = 'ItemText';

ATI.Ajax.Controls.AutoComplete.ExtendedAutoComplete = function(element) {
    ATI.Ajax.Controls.AutoComplete.ExtendedAutoComplete.initializeBase(this, [element]);
    this._useKeyValueMode = false;
    this._keyValueSeparator = "$";
    this._postBackUrl = '';
    this._prepareTextJS = '';
    this._keyEnterHandler = Function.createDelegate(this, this._onKeyDown2);
    $addHandler(element, "keypress", this._keyEnterHandler);
    //$addHandler(element, "keydown", this._keyEnterHandler);      
    this._postBackHandler = null;
    this._emptyKey = "$empty$";
    this._lastSelectedText = '';
}

ATI.Ajax.Controls.AutoComplete.ExtendedAutoComplete.prototype = {

  dispose: function() {
    var element = this.get_element();
    $removeHandler(element, "keypress", this._keyEnterHandler);
    this._keyEnterHandler = null;

    if (this._postBackHandler != null) {
      if (element.form)
        $removeHandler(element.form, "submit", this._postBackHandler);
      this._postBackHandler = null;
    }
    ATI.Ajax.Controls.AutoComplete.ExtendedAutoComplete.callBaseMethod(this, 'dispose');
  },

  ///new functions    
  set_keyValueSeparator: function(value) {
    /// <summary>
    /// Sets the Special Character that will be used to split the Key-Value Pair 
    /// </summary>
    /// <param name="value" type="String" DomElement="false" mayBeNull="false" />
    /// <returns />
    this._keyValueSeparator = value;
  },
  get_keyValueSeparator: function(value) {

    return this._keyValueSeparator;
  },

  set_useKeyValueMode: function(value) {
    /// <summary>
    /// Enables / Disables the KeyValue Pair Mode 
    /// </summary>
    /// <param name="value" type="Boolean" DomElement="false" mayBeNull="false" />
    /// <returns />
    this._useKeyValueMode = value;
  },
  get_useKeyValueMode: function() {
    return this._useKeyValueMode;
  },

  set_postBackUrl: function(value) {
    /// <summary>
    /// Sets PostBackUrl of the control 
    /// </summary>
    /// <param name="value" type="String" DomElement="false" mayBeNull="true" />
    /// <returns />
    this._postBackUrl = value;
  },
  get_postBackUrl: function() {
    if (this._postBackUrl == null)
      this._postBackUrl = '';
    return this._postBackUrl;
  },

  set_prepareTextJS: function(value) {
    /// <summary>
    /// Sets the JS function to modify the item text
    /// </summary>
    /// <param name="value" type="String" DomElement="false" mayBeNull="true" />
    /// <returns />
    this._prepareTextJS = value;
  },
  get_prepareTextJS: function() {
    if (this._prepareTextJS == null)
      this._prepareTextJS = '';
    return this._prepareTextJS;
  },


  _createValueNode: function(value) {
    var _valueNode = document.createElement("input"); // type='hidden'/>");
    _valueNode.type = "hidden";
    _valueNode.value = value;
    return _valueNode;
  },
  _extractText: function(keyValuePair) {
    return keyValuePair.split(this._keyValueSeparator)[0];
  },
  _extractValue: function(keyValuePair) {
    return keyValuePair.split(this._keyValueSeparator)[1];
  },

  _onKeyDown2: function(ev) {
    /// <summary>
    /// Handler for the textbox keydown event to change postback url if needed
    /// </summary>
    /// <param name="ev" type="Sys.UI.DomEvent" DomElement="false" mayBeNull="false" />
    /// <returns />
    var k = ev.keyCode ? ev.keyCode : ev.rawEvent.keyCode;
    if (k === Sys.UI.Key.enter) {
      var element = this.get_element();
      if ((!this._timer.get_enabled() || Sys.Browser.agent == Sys.Browser.Opera) &&
            this.get_postBackUrl() != '' && element.form) {
        this._postBackHandler = Function.createDelegate(this, this._onSubmit);
        $addHandler(element.form, "submit", this._postBackHandler);
      }
      if ((Sys.Browser.agent == Sys.Browser.Firefox || Sys.Browser.agent == Sys.Browser.Opera)
          && this._lastSelectedText != element.value) {
        this._lastSelectedText = element.value;
        ev.rawEvent.cancelBubble = true;
        ev.rawEvent.returnValue = false;
        return false;
      }
    }
  },

  _onSubmit: function() {
    this.get_element().form.action = this.get_postBackUrl();
  },

  add_selectionCompleted: function(handler) {
    /// <summary>
    /// Add an event handler for the selectionCompleted event
    /// </summary>
    /// <param name="handler" type="Function" mayBeNull="false">
    /// Event handler
    /// </param>
    /// <returns />
    this.get_events().addHandler('selectionCompleted', handler);
  },
  remove_selectionCompleted: function(handler) {
    /// <summary>
    /// Remove an event handler from the selectionCompleted event
    /// </summary>
    /// <param name="handler" type="Function" mayBeNull="false">
    /// Event handler
    /// </param>
    /// <returns />
    this.get_events().removeHandler('selectionCompleted', handler);
  },
  raise_selectionCompleted: function(eventArgs) {
    /// <summary>
    /// Raise the selectionCompleted event
    /// </summary>
    /// <param name="eventArgs" type="AjaxControlToolkit.AutoCompleteItemEventArgs" mayBeNull="false">
    /// Event arguments for the selectionCompleted event
    /// </param>
    /// <returns />

    var handler = this.get_events().getHandler('selectionCompleted');
    if (handler) {
      handler(this, eventArgs);
    }
  },

  ///modified functions

  _hideCompletionList: function() {
    ATI.Ajax.Controls.AutoComplete.ExtendedAutoComplete.callBaseMethod(this, '_hideCompletionList');
    if (this._currentPrefix == this._emptyKey)
      this._currentPrefix = '';
  },

  _onTimerTick: function(sender, eventArgs) {
    /// <summary>
    /// Handler invoked when a timer tick occurs
    /// </summary>
    /// <param name="sender" type="Object" mayBeNull="true"/>
    /// <param name="eventArgs" type="Sys.EventArgs" mayBeNull="true" />        
    /// <returns />  

    if (this._servicePath && this._serviceMethod) {
      var text = this._currentCompletionWord();

      if (text == "" && this._minimumPrefixLength == 0)
        text = this._emptyKey;

      if (text.trim().length < this._minimumPrefixLength) {
        this._currentPrefix = null;
        this._update('', null, /* cacheResults */false);
        return;
      }
      // there is new content in the textbox or the textbox is empty but the min prefix length is 0
      if (this._currentPrefix !== text) {
        this._currentPrefix = text;
        if (text != "" && this._cache && this._cache[text]) {
          this._update(text, this._cache[text], /* cacheResults */false);
          return;
        }
        // Raise the populating event and optionally cancel the web service invocation
        var eventArgs = new Sys.CancelEventArgs();
        this.raisePopulating(eventArgs);
        if (eventArgs.get_cancel()) {
          return;
        }

        // Create the service parameters and optionally add the context parameter
        // (thereby determining which method signature we're expecting...)
        var params = { prefixText: (this._currentPrefix == this._emptyKey) ? "" : this._currentPrefix,
          count: this._completionSetCount
        };
        if (this._useContextKey) {
          params.contextKey = this._contextKey;
        }

        // Invoke the web service
        Sys.Net.WebServiceProxy.invoke(this.get_servicePath(), this.get_serviceMethod(), false, params,
                                            Function.createDelegate(this, this._onMethodComplete),
                                            Function.createDelegate(this, this._onMethodFailed),
                                            text);
        $common.updateFormToRefreshATDeviceBuffer();
      }
    }
  },

  _setText: function(item) {
    /// <summary>
    /// Method to set the selected autocomplete option on the textbox
    /// </summary>
    /// <param name="item" type="Sys.UI.DomElement" DomElement="true" mayBeNull="true">
    /// Item to select
    /// </param>
    /// <returns />

    //debugger;
    var parentElement = item.parentNode;
    var iCount = 0;

    while (parentElement != null &&
            parentElement !== this._completionListElement) {
      iCount++;
      parentElement = parentElement.parentNode;
    }

    if (parentElement == null)
      return;

    if (iCount > 0)
      while (iCount != 0) {
      item = item.parentNode;
      iCount--;
    }

    var text = (item && item.firstChild) ? item.firstChild.getAttribute(ATTR_NAME) : null;

    var value = null;
    if (this._useKeyValueMode)
      value = (item && item.firstChild.nextSibling) ? item.firstChild.nextSibling.value : null;
    var args = new AjaxControlToolkit.AutoCompleteItemEventArgs(item, text, value);
    this.raiseItemSelected(args);

    this._timer.set_enabled(false);

    var element = this.get_element();
    var control = element.control;
    if (control && control.set_text) {
      control.set_text(text);
      $common.tryFireEvent(control, "change");
    }
    else {
      element.value = text;
      $common.tryFireEvent(element, "change");
    }
    this._currentPrefix = this._currentCompletionWord();
    this._hideCompletionList();
    this.raise_selectionCompleted(args);
  },

  _update: function(prefixText, completionItems, cacheResults) {
    /// <summary>
    /// Method to update the status of the autocomplete behavior
    /// </summary>
    /// <param name="prefixText" type="String" DomElement="false" mayBeNull="true" />
    /// <param name="completionItems" type="Object" DomElement="false" mayBeNull="true" />
    /// <param name="cacheResults" type="Object" DomElement="false" mayBeNull="true" />
    /// <returns />

    if (!this._textBoxHasFocus) {
      this._hideCompletionList();
      return;
    }

    if (cacheResults && this.get_enableCaching()) {
      if (!this._cache) {
        this._cache = {};
      }
      this._cache[prefixText] = completionItems;
    }

    if (completionItems && completionItems.length) {
      this._completionListElement.innerHTML = '';
      this._selectIndex = -1;
      var _firstChild = null;
      var _text = "";
      var _value = "";



      for (var i = 0; i < completionItems.length; i++) {

        //If We are using the  KeyValue Pair Mode
        if (this._useKeyValueMode) {
          _text = this._getTextWithInsertedWord(completionItems[i].Text);
          _value = this._getTextWithInsertedWord(completionItems[i].Value);
        }
        else {
          _text = this._getTextWithInsertedWord(completionItems[i]);
        }
        var itemElement = null;
        if (this._completionListElementID) {
          // the completion element has been created by the user and li won't necessarily work
          itemElement = document.createElement('div');
        } else {
          itemElement = document.createElement('li');
        }

        // set the first child if it is null
        if (_firstChild == null) {
          _firstChild = itemElement;
        }

        var textElement = document.createElement('span');
        textElement.setAttribute(ATTR_NAME, _text);
        textElement.innerHTML = this._prepareItemText(_text); ;

        itemElement.appendChild(/*document.createTextNode(_text)*/textElement);
        //If We are using the  KeyValue Pair Mode , we add a Hidden Field to the LI to store the value of the Item
        if (this._useKeyValueMode) {
          itemElement.appendChild(this._createValueNode(_value));
        }
        itemElement.__item = '';

        if (this._completionListItemCssClass) {
          Sys.UI.DomElement.addCssClass(itemElement, this._completionListItemCssClass);
        } else {
          var itemElementStyle = itemElement.style;
          itemElementStyle.padding = '0px';
          itemElementStyle.textAlign = 'left';
          itemElementStyle.textOverflow = 'ellipsis';
          // workaround for safari since normal colors do not
          // show well there.
          if (Sys.Browser.agent === Sys.Browser.Safari) {
            itemElementStyle.backgroundColor = 'white';
            itemElementStyle.color = 'black';
          } else {
            itemElementStyle.backgroundColor = this._textBackground;
            itemElementStyle.color = this._textColor;
          }
        }
        this._completionListElement.appendChild(itemElement);
      }
      var elementBounds = $common.getBounds(this.get_element());
      this._completionListElement.style.width = Math.max(1, elementBounds.width - 2) + 'px';
      this._completionListElement.scrollTop = 0;

      this.raisePopulated(Sys.EventArgs.Empty);

      var eventArgs = new Sys.CancelEventArgs();
      this.raiseShowing(eventArgs);
      if (!eventArgs.get_cancel()) {
        this.showPopup();
        if (Sys.Browser.agent === Sys.Browser.InternetExplorer) {
          var listBounds = $common.getBounds(this._completionListElement);
          var elementBounds = $common.getBounds(this.get_element());
          if (listBounds.y < elementBounds.y &&
                        document.body.scrollTop > 0) {
            listBounds.y = elementBounds.y + elementBounds.height + document.body.scrollTop;
            $common.setBounds(this._completionListElement, listBounds);
          }
        }
        // Check if the first Row is to be selected by default and if yes highlight it and updated selectIndex.
        if (this._firstRowSelected && (_firstChild != null)) {
          this._highlightItem(_firstChild);
          this._selectIndex = 0;
        }
      }
    } else {
      this._hideCompletionList();
    }
  },

  _prepareItemText: function(p_text) {

    var sReturn = p_text;
    var sJS = this.get_prepareTextJS();
    if (sJS != null &&
            sJS != '') {
      try {
        var fn = eval(sJS);
        if (fn != null)
          sReturn = fn.call(null, p_text);
      }
      catch (e) {
      }
    }
    return sReturn;
  }
}

ATI.Ajax.Controls.AutoComplete.ExtendedAutoComplete.registerClass('ATI.Ajax.Controls.AutoComplete.ExtendedAutoComplete', 
    AjaxControlToolkit.AutoCompleteBehavior);

ATI.Ajax.Controls.AutoComplete.ExtendedAutoComplete.descriptor = AjaxControlToolkit.AutoCompleteBehavior.descriptor;
Array.addRange(ATI.Ajax.Controls.AutoComplete.ExtendedAutoComplete.descriptor.properties,
    [{name: 'keyValueSeparator', type: String}, {name: 'useKeyValueMode', type: Boolean},
     {name: 'postBackUrl', type: String}, {name: 'prepareTextJS', type: String}]);

///class redefinition

AjaxControlToolkit.AutoCompleteItemEventArgs = function(item, text,value) {
    /// <summary>
    /// Event arguments used when the itemSelected event is raised
    /// </summary>
    /// <param name="item" type="Sys.UI.DomElement" DomElement="true" mayBeNull="true">
    /// Item
    /// </param>
    /// <param name="text" type="String" mayBeNull="true">
    /// Text of the item
    /// </param>
    /// <param name="value" type="String" mayBeNull="true">
    /// Value of the item
    /// </param>
    AjaxControlToolkit.AutoCompleteItemEventArgs.initializeBase(this);
    
    this._item  = item;
    this._text  = text;
    this._value = value;
}
AjaxControlToolkit.AutoCompleteItemEventArgs.prototype = {
    get_item : function() {
        /// <value type="Sys.UI.DomElement" DomElement="true" mayBeNull="true">
        /// Item
        /// </value>
        return this._item;
    },
    set_item : function(value) {
        this._item = value;
    },
    
    get_text : function() {
        /// <value type="String" maybeNull="true">
        /// Text of the item
        /// </value>
        return this._text;
    },
    set_text : function(value) {
        this._text = value;
    },
    set_value : function ( value ) {
        this._value = value;
    },
    get_value : function (  ) {
        return this._value;
    }
}

function DefaultPrepareItemText(p_text)
{
    var sReturn = p_text;
    try
    {
        if (p_text != null &&
            p_text != '')
            {
                var aText = p_text.split(',');
                if (aText.length > 2)
                    aText[0] = String.format('<b>{0}</b>', aText[0]);
                if (aText.length > 1)
                    aText[aText.length - 2] = String.format('<i>{0}</i>', aText[aText.length - 2]);
                    
                sReturn = '';                
                for (var i = 0; i < aText.length; ++i)
                    sReturn = sReturn + (sReturn == '' ? '' : ',') + aText[i];
            }
    }
    catch(e)
    {        
    }
    return sReturn;
}
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();