﻿Type.registerNamespace("TitanTV");

// Constructor
TitanTV.AdvancedSearch = function(element)
{
  TitanTV.AdvancedSearch.initializeBase(this, [element]);

  // Private variables
  this._defaultQueryText = null;

  // UI Elements
  this.queryBox = null;
  this.searchName = null;
  this.searchTerms = null;
  this.phrase = null
  this.orTerm1 = null;
  this.orTerm2 = null;
  this.orTerm3 = null;
  this.excludeTerms = null;
  this.lineupList = null;
  this.channel = null;
  this.daysList = null;
  this.fieldList = null;
  this.hdOnly = null;
  this.ccOnly = null;
  this.moviesOnly = null;
  this.newOnly = null;
  this.resultFormatList = null;
  this.resultSortList = null;
  this.submitButton = null;
  this.queryError = null;
  this.nameError = null;
  this.queryText = null;

  // Private methods
  this.onKeyUp = null;
  this.onSelectedIndexChanged = null;
  this.onClick = null;
  this.buildQuery = null;
}

TitanTV.AdvancedSearch.prototype = {

  // property accessors.

  get_defaultQueryText: function() { return this.defaultQueryText; },
  set_defaultQueryText: function(value) { this.defaultQueryText = value; },

  get_queryBox: function() { return this.queryBox; },
  set_queryBox: function(value) { this.queryBox = value; },

  get_searchName: function() { return this.searchName; },
  set_searchName: function(value) { this.searchName = value; },

  get_searchTerms: function() { return this.searchTerms; },
  set_searchTerms: function(value) { this.searchTerms = value; },

  get_phrase: function() { return this.phrase; },
  set_phrase: function(value) { this.phrase = value; },

  get_orTerm1: function() { return this.orTerm1; },
  set_orTerm1: function(value) { this.orTerm1 = value; },

  get_orTerm2: function() { return this.orTerm2; },
  set_orTerm2: function(value) { this.orTerm2 = value; },

  get_orTerm3: function() { return this.orTerm3; },
  set_orTerm3: function(value) { this.orTerm3 = value; },

  get_excludeTerms: function() { return this.excludeTerms; },
  set_excludeTerms: function(value) { this.excludeTerms = value; },

  get_lineupList: function() { return this.lineupSelector; },
  set_lineupList: function(value) { this.lineupSelector = value; },

  get_channel: function() { return this.channel; },
  set_channel: function(value) { this.channel = value; },

  get_daysList: function() { return this.daysList; },
  set_daysList: function(value) { this.daysList = value; },

  get_fieldList: function() { return this.fieldList; },
  set_fieldList: function(value) { this.fieldList = value; },

  get_hdOnly: function() { return this.hdOnly; },
  set_hdOnly: function(value) { this.hdOnly = value; },

  get_ccOnly: function() { return this.ccOnly; },
  set_ccOnly: function(value) { this.ccOnly = value; },

  get_moviesOnly: function() { return this.moviesOnly; },
  set_moviesOnly: function(value) { this.moviesOnly = value; },

  get_newOnly: function() { return this.newOnly; },
  set_newOnly: function(value) { this.newOnly = value; },

  get_resultFormatList: function() { return this.resultFormatList; },
  set_resultFormatList: function(value) { this.resultFormatList = value; },

  get_resultSortList: function() { return this.resultSortList; },
  set_resultSortList: function(value) { this.resultSortList = value; },

  get_submitButton: function() { return this.submitButton; },
  set_submitButton: function(value) { this.submitButton = value; },

  get_queryText: function() { return this.queryText; },
  set_queryText: function(value) { this.queryText = value; },

  initialize: function()
  {
    var element = this.get_element();

    if (this.queryBox) this.defaultQueryText = this.queryBox.innerHTML;

    this.queryError = $get("queryError", element);
    this.nameError = $get("nameError", element);

    // create Delgates
    if (this.onKeyUp === null) this.onKeyUp = Function.createDelegate(this, this._onKeyUp);
    if (this.buildQuery === null) this.buildQuery = Function.createDelegate(this, this._buildQuery);
    if (this.onSelectedIndexChanged === null) this.onSelectedIndexChanged = Function.createDelegate(this, this._onSelectedIndexChanged);
    if (this.onClick === null) this.onClick = Function.createDelegate(this, this._onClick);

    if (this.searchTerms) $addHandler(this.searchTerms, 'keyup', this.onKeyUp);
    if (this.phrase) $addHandler(this.phrase, 'keyup', this.onKeyUp);
    if (this.orTerm1) $addHandler(this.orTerm1, 'keyup', this.onKeyUp);
    if (this.orTerm2) $addHandler(this.orTerm2, 'keyup', this.onKeyUp);
    if (this.orTerm3) $addHandler(this.orTerm3, 'keyup', this.onKeyUp);
    if (this.excludeTerms) $addHandler(this.excludeTerms, 'keyup', this.onKeyUp);
    if (this.channel) $addHandler(this.channel, 'keyup', this.onKeyUp);
    if (this.daysList) this.daysList.add_selectedIndexChanged(this.onSelectedIndexChanged);
    if (this.fieldList) this.fieldList.add_selectedIndexChanged(this.onSelectedIndexChanged);
    if (this.resultFormatList) this.resultFormatList.add_selectedIndexChanged(this.onSelectedIndexChanged);
    if (this.resultSortList) this.resultSortList.add_selectedIndexChanged(this.onSelectedIndexChanged);
    if (this.hdOnly) $addHandler(this.hdOnly, 'click', this.onClick);
    if (this.ccOnly) $addHandler(this.ccOnly, 'click', this.onClick);
    if (this.moviesOnly) $addHandler(this.moviesOnly, 'click', this.onClick);
    if (this.newOnly) $addHandler(this.newOnly, 'click', this.onClick);

    if (this.submitButton) $addHandler(this.submitButton, 'click', this.onClick);

    TitanTV.AdvancedSearch.callBaseMethod(this, 'initialize');

    Sys.Debug.trace('Initialize: ' + element.id);
  },

  // Release resources before control is disposed.
  dispose: function()
  {
    var element = this.get_element();

    if (this.searchTerms) $clearHandlers(this.searchTerms);
    if (this.phrase) $clearHandlers(this.phrase);
    if (this.orTerm1) $clearHandlers(this.orTerm1);
    if (this.orTerm2) $clearHandlers(this.orTerm2);
    if (this.orTerm3) $clearHandlers(this.orTerm3);
    if (this.excludeTerms) $clearHandlers(this.excludeTerms);
    if (this.channel) $clearHandlers(this.channel);
    if (this.hdOnly) $clearHandlers(this.hdOnly);
    if (this.ccOnly) $clearHandlers(this.ccOnly);
    if (this.moviesOnly) $clearHandlers(this.moviesOnly);
    if (this.newOnly) $clearHandlers(this.newOnly);

    if (this.daysList) this.daysList.remove_selectedIndexChanged(this.onSelectedIndexChanged);
    if (this.fieldList) this.fieldList.remove_selectedIndexChanged(this.onSelectedIndexChanged);
    if (this.resultFormatList) this.resultFormatList.remove_selectedIndexChanged(this.onSelectedIndexChanged);
    if (this.resultSortList) this.resultSortList.remove_selectedIndexChanged(this.onSelectedIndexChanged);

    if (this.submitButton) $clearHandlers(this.submitButton);

    if (this.onKeyUp) delete this.onKeyUp;
    if (this.buildQuery) delete this.buildQuery;
    if (this.onSelectedIndexChanged) delete this.onSelectedIndexChanged;
    if (this.onClick) delete this.onClick;

    TitanTV.AdvancedSearch.callBaseMethod(this, 'dispose');

    Sys.Debug.trace('Dispose: ' + element.id);
  },

  _onSearchClick: function(e)
  {
    return true;
  },

  _onKeyUp: function(e)
  {
    //var input = e.target;

    this.buildQuery();
  },

  _onSelectedIndexChanged: function(e)
  {
    //var input = e.target;

    this.buildQuery();
  },

  _onClick: function(e)
  {
    this.buildQuery();

    if (e.target == this.submitButton)
    {
      var terms = this.searchTerms.value

      if (this.phrase) terms += this.phrase.value;
      if (this.orTerm1) terms += this.orTerm1.value;
      if (this.orTerm2) terms += this.orTerm2.value;
      if (this.orTerm3) terms += this.orTerm3.value;

      // Always have to have a search term
      if (terms.trim() == "")
      {
        if (this.queryError) this.queryError.style.display = 'inline';
        e.preventDefault();
      }

      // If the search name field is present, make sure it's populated
      if (this.searchName && this.searchName.value.trim() == "")
      {
        if (this.nameError) this.nameError.style.display = 'inline';
        e.preventDefault();
      }
    }
  },

  _buildQuery: function()
  {
    if (this.error) this.error.style.display = 'none';

    // SearchTerms
    var query = this.encodeHTML(this.searchTerms.value, false, true);

    // Phrase
    if (this.phrase)
    {
      var phraseText = this.encodeHTML(this.phrase.value, true, true);
      if (phraseText != "")
      {
        if (query != "") query += " ";
        query += "<b>&quot;</b>" + phraseText + "<b>&quot;</b>";
      }
    }

    // OrTerms

    var orTerms = "";
    var hasSpace = /\s/;
    var hasMultipleOrTerms = false;

    if (this.orTerm1)
    {
      var ot1 = this.encodeHTML(this.orTerm1.value, true, true);
      if (hasSpace.test(ot1)) ot1 = "<b>&quot;</b>" + ot1 + "<b>&quot;</b>";
      if (ot1 != null && ot1 != "")
      {
        hasMultipleOrTerms = (orTerms != "") ? true : false;
        orTerms += hasMultipleOrTerms ? " <b>OR</b> " + ot1 : ot1;
      }
    }

    if (this.orTerm2)
    {
      var ot2 = this.encodeHTML(this.orTerm2.value, true, true);
      if (hasSpace.test(ot2)) ot2 = "<b>&quot;</b>" + ot2 + "<b>&quot;</b>";
      if (ot2 != null && ot2 != "")
      {
        hasMultipleOrTerms = (orTerms != "") ? true : false;
        orTerms += hasMultipleOrTerms ? " <b>OR</b> " + ot2 : ot2;
      }
    }

    if (this.orTerm3)
    {
      var ot3 = this.encodeHTML(this.orTerm3.value, true, true);
      if (hasSpace.test(ot3)) ot3 = "<b>&quot;</b>" + ot3 + "<b>&quot;</b>";
      if (ot3 != null && ot3 != "")
      {
        hasMultipleOrTerms = (orTerms != "") ? true : false;
        orTerms += hasMultipleOrTerms ? " <b>OR</b> " + ot3 : ot3;
      }
    }

    if (orTerms != "")
    {
      if (query != "") query += " ";
      query += " " + hasMultipleOrTerms ? "<b>(</b>" + orTerms + "<b>)</b>" : orTerms;
    }

    // ExcludeTerms
    if (this.excludeTerms)
    {
      var excludeTermsExp = /("([^"\\]*(\\.[^"\\]*)*)"|\w+)/g;
      var excludeTermsMatches = this.excludeTerms.value.match(excludeTermsExp);
      if (excludeTermsMatches)
      {
        for (var i = 0; i < excludeTermsMatches.length; i++)
        {
          var excludeTerm = this.encodeHTML(excludeTermsMatches[i], false, false);
          if (excludeTerm != "")
          {
            if (query != "") query += " ";
            query += "-" + excludeTerm;
          }
        }
      }
    }

    // Channel
    var channelExp = /[a-zA-Z_0-9.-]+/
    var channelMatch = this.channel.value.match(channelExp);
    if (channelMatch && channelMatch.length > 0)
    {
      var channel = this.encodeHTML(channelMatch[0], false, false);
      if (channel != "")
      {
        if (query != "") query += " ";
        query += "channel:" + channel;
      }
    }

    // Days
    if (this.daysList && this.daysList.get_value() != "7")
    {
      if (query != "") query += " ";
      query += "days:" + this.daysList.get_value();
    }

    // Fields
    if (this.fieldList)
    {
      if (this.fieldList.get_value() == "1")
      {
        if (query != "") query += " ";
        query += "/title";
      }
      if (this.fieldList.get_value() == "2")
      {
        if (query != "") query += " ";
        query += "/titlestartswith";
      }
      if (this.fieldList.get_value() == "3")
      {
        if (query != "") query += " ";
        query += "/titleequals";
      }
      if (this.fieldList.get_value() == "4")
      {
        if (query != "") query += " ";
        query += "/titleendswith";
      }
    }

    // hd
    if (this.hdOnly.checked)
    {
      if (query != "") query += " ";
      query += "/hd";
    }

    // cc
    if (this.ccOnly.checked)
    {
      if (query != "") query += " ";
      query += "/cc";
    }

    // movies
    if (this.moviesOnly.checked)
    {
      if (query != "") query += " ";
      query += "/movies";
    }

    // new
    if (this.newOnly.checked)
    {
      if (query != "") query += " ";
      query += "/new";
    }

    // Format
    if (this.resultFormatList && this.resultFormatList.get_value() == "1")
    {
      if (query != "") query += " ";
      query += "view:grid";
    }

    // Sort
    if (this.resultSortList && this.resultSortList.get_value() != "")
    {
      if (query != "") query += " ";
      query += "sort:" + this.resultSortList.get_value();
    }

    if (this.queryBox) this.queryBox.innerHTML = (query == null || query == "") ? this.defaultQueryText : query;

    // Combined value sent back to page for the case where multiple fields make up the query
    if (this.queryText) this.queryText.value = query.replace(/(<([^>]+)>)/ig, "");
  },

  encodeHTML: function(input, removeQuotes, trim)
  {
    if (input == null) return "";

    var div = document.createElement('div');
    var text = document.createTextNode(removeQuotes ? input.replace(/"/ig, "") : input);
    div.appendChild(text);

    return trim ? div.innerHTML.trim() : div.innerHTML;
  }
}

TitanTV.AdvancedSearch.registerClass('TitanTV.AdvancedSearch', Sys.UI.Control);

// Since this script is not loaded by System.Web.Handlers.ScriptResourceHandler
// invoke Sys.Application.notifyScriptLoaded to notify ScriptManager 
// that this is the end of the script.
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();
