/**
 * OND Lists
 *   Implementation of the Origin and Destination lists functions
 * @author Ramy Deeb [radeeb@copaair.com]
 * @version 1.0
 * @uses jQuery
 */

/**
 * listObject storage class
 */
var listObject = function()
{
  this.jsonData;
  this.myContainer;
  this.defaultList;
  this.selected;
  this.textBox;
  this.dependant;
  this.cityexist;
}
 
/**
 * appendList: appends a list to a textbox object;
 * @param {String} textBox_id
 * @param {String} container
 * @param {String} selectedCity
 * @param {Object} dependant
 */
var appendList = function (textBox_id, container, selectedCity, dependant)
{
  //Variables
  var myObject =  new listObject();  
  myObject.myContainer = createList(container);  
  myObject.textBox = $('#' + textBox_id);
  myObject.dependant = dependant;
  if (dependant != null)
  {
    loadData('', myObject, false);
	loadData(selectedCity, myObject.dependant, false);
	myObject.cityexist = true;
	if(selectedCity !='')
	{
		myObject.dependant.cityexist = true;	
	}
  }
  
  //Event handling
  
  myObject.textBox.bind("click", function(){
    //Handle click function
	if(myObject.cityexist)
	{
    myObject.myContainer.remove();
    myObject.myContainer = createList(container);
    var offset = myObject.textBox.offset();
    myObject.myContainer.css('left', offset.left);
    myObject.myContainer.css('top', offset.top + 21);
    myObject.myContainer.html(buildList(myObject.jsonData, myObject));
    showList(myObject.myContainer);
    }
  });
  
  myObject.textBox.bind("blur", function(){
    //Handle blur function
    blurCitypopup(container, textBox_id, myObject.myContainer);
  });
  myObject.textBox.bind("keyup", function(){
    //Handle keyup function
	 myObject.textBox.trigger("click");
    myObject.myContainer.html(myObject.defaultList);
    myObject.myContainer.html(searchDestination(myObject.jsonData, myObject.textBox.val(), myObject));
    $(myObject.myContainer).bgiframe();
  });  
  myObject.textBox.bind("focus", function(){ if(jQuery.trim(myObject.textBox.val()).length==0) { myObject.textBox.trigger("click"); } });  
  
  hideList(myObject.myContainer);
  this.myObject = myObject;
  return myObject;
}

/**
 * createList: creates the list object
 * @param {String} container
 */
var createList = function(container)
{
  var check;
  if (check = $('#' + container))
    check.remove();
  var tmpContainer = $('<div id="' + container + '"></div>');
  $('body').append(tmpContainer);
  tmpContainer.hide();
  return tmpContainer;
}

/**
 * showList: shows an specified list
 * @param {Object} theObject
 * modified by Julio Obispo
 * 06/08/2009
 * added call for bgiframe
 * for added frame
 * in IE6 for display
 * Pop up over
 * select
 */
var showList = function(theObject)
{
  $(theObject).bgiframe();
  theObject.css('display','');
  theObject.show();
}

/**
 * hideList: hides an specified list
 * @param {Object} theObject
 */
var hideList = function(theObject)
{
  theObject.hide();
}

/**
 * loadData: loads the json data
 * @param {String} airportCode
 * @param {Object} object
 */
var loadData = function(airportCode, object, check)
{
  if (airportCode && airportCode != '')
  {
    $.ajax({
      type: "GET",
      url: '/_layouts/GetONDList.ashx?originCode=' + airportCode,
      success: function(data){
        object.jsonData = JSON.parse(data);
        object.defaultList = buildList(object.jsonData, object);
		if (check)
		{
		  if (!inList(object.textBox.val(), JSON.parse(data)))
		  {
			object.textBox.val('');
		  }
		}
      }
    });
  }
  else
  {
    $.ajax({
      type: "GET",
      url: "/_layouts/GetONDList.ashx",
      success: function(data){  
        object.jsonData = JSON.parse(data);
        object.defaultList = buildList(object.jsonData, object);
		if (object.dependant && object.selected)
       {
         if (!inList(object.selected, object.dependant.jsonData))
         {
           object.dependant.textbox.val('');
         }
       }
      }
    });
	return object.jsonData;
  }
}

/**
 * buildList: creates the main HTML list
 * @param {Object} data
 * @param {Object} object
 */
var buildList = function(data, object)
{
  var j = 0;
  var tmpList = '';
  tmpList = $('<span></span>');
  innerList = $('<ul></ul>');
  $.each(data.routes, function(i,item)
  {
    if (j == 14){
      tmpList.append(innerList);
      innerList = $('<ul></ul>');
      j = 0;
    }
    innerList.append(buildLink(item.code, item.name, object));
    j += 1;
  });
  tmpList.append(innerList);
  return tmpList;
}

/**
 * searchDestination: search the text in the destination list
 * @param {Object} data
 * @param {String} text
 * @param {Object} object
 */
var searchDestination = function(data, text, object)
{
  var j = 0;
  tmpList = $('<span></span>');
  innerList = $('<ul></ul>');
  if (text.length >= 3)
    $.each(data.routes, function(i,item)
    {
      if (j == 14){
        tmpList.append(innerList);
        innerList = $('<ul></ul>');
        j = 0;
      }
      code = replaceSpecialChars(item.code.toLowerCase());
      name = replaceSpecialChars(item.name.toLowerCase());
      if (code.match(replaceSpecialChars(text.toLowerCase())) || name.match(replaceSpecialChars(text.toLowerCase()))) {
        innerList.append(buildLink(item.code, item.name, object));
        j += 1;
      }
    });
    tmpList.append(innerList);
  if(text.length < 3 && text.length > 0)
    return $('<ul><li>Escriba tres letras o mas para buscar su destino</li></ul>');
  if (text.length > 0)
    return tmpList;
  else
    return buildList(object.jsonData, object);;
}

var replaceSpecialChars = function(text)
{
  tmpText = text;
  tmpText = tmpText.replace(/\u00E1/g, 'a');
  tmpText = tmpText.replace(/\u00E9/g, 'e');
  tmpText = tmpText.replace(/\u00ED/g, 'i');
  tmpText = tmpText.replace(/\u00F3/g, 'o');
  tmpText = tmpText.replace(/\u00FA/g, 'u');
  return tmpText;
}

/**
 * handleBlur: handles when the user clicks outside the container
 * @param {Object} Container
 * @param {Object} textBox
 * @param {Object} listObject
 */
var blurCitypopup = function(Container, textBox, listObject)
{
  var Event = YAHOO.util.Event,
      Dom = YAHOO.util.Dom;
  var textBox = Dom.get(textBox);
  var icon = Dom.get(icon);
  Event.on(document, "click", function(e) {
    var el = Event.getTarget(e);
    var dialogEl = Dom.get(Container);
    if (el != dialogEl && !Dom.isAncestor(dialogEl, el) && el != textBox &&  !Dom.isAncestor(textBox, el) ) {
      hideList(listObject);
    }
  });
}

/**
 * buildLink: builds a link and it appends the on click functions
 * @param {String} code
 * @param {String} name
 * @param {Object} object
 */
var buildLink = function(code, name, object)
{
  var li = $('<li></li>');
  var a = $('<a href="#">'+ name + '<span class="code">' + code + '</span></a>');
  a.unbind();
  a.bind("click", function(){
    object.textBox.val(name + " " + code);
    object.selected = code;
    if (object.dependant)
    {
      object.dependant.cityexist = true;
      loadData(code,object.dependant, true);
    }
    hideList(object.myContainer);
    return false;
  });
  li.append(a);
  return li;
}

/**
 * search if a code is in a code list
 * @param {Object} origin
 * @param {Object} destination
 */
var inList = function(code, list)
{
  for(var i=0;i < list.routes.length;i++)
  {
	var tmpStr = list.routes[i].name + " " + list.routes[i].code;
    if (code.match(tmpStr) != null)
    {
      return true;
    }
  }
  return false;
}

//JSON parser implementation by json.org
if (!this.JSON) {
    JSON = {};
}
(function () {
    function f(n) {
        return n < 10 ? '0' + n : n;
    }

    if (typeof Date.prototype.toJSON !== 'function') {

        Date.prototype.toJSON = function (key) {

            return this.getUTCFullYear()   + '-' +
                 f(this.getUTCMonth() + 1) + '-' +
                 f(this.getUTCDate())      + 'T' +
                 f(this.getUTCHours())     + ':' +
                 f(this.getUTCMinutes())   + ':' +
                 f(this.getUTCSeconds())   + 'Z';
        };
        String.prototype.toJSON =
        Number.prototype.toJSON =
        Boolean.prototype.toJSON = function (key) {
            return this.valueOf();
        };
    }
    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        gap,
        indent,
        meta = {
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        },
        rep;
    function quote(string) {

        escapable.lastIndex = 0;
        return escapable.test(string) ?
            '"' + string.replace(escapable, function (a) {
                var c = meta[a];
                return typeof c === 'string' ? c :
                    '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
            }) + '"' :
            '"' + string + '"';
    }
    function str(key, holder) {
        var i,          
            k,          
            v,          
            length,
            mind = gap,
            partial,
            value = holder[key];
        if (value && typeof value === 'object' &&
                typeof value.toJSON === 'function') {
            value = value.toJSON(key);
        }
        if (typeof rep === 'function') {
            value = rep.call(holder, key, value);
        }
        switch (typeof value) {
        case 'string':
            return quote(value);
        case 'number':
            return isFinite(value) ? String(value) : 'null';
        case 'boolean':
        case 'null':
            return String(value);
        case 'object':
            if (!value) {
                return 'null';
            }
            gap += indent;
            partial = [];
            if (Object.prototype.toString.apply(value) === '[object Array]') {
                length = value.length;
                for (i = 0; i < length; i += 1) {
                    partial[i] = str(i, value) || 'null';
                }
                v = partial.length === 0 ? '[]' :
                    gap ? '[\n' + gap +
                            partial.join(',\n' + gap) + '\n' +
                                mind + ']' :
                          '[' + partial.join(',') + ']';
                gap = mind;
                return v;
            }
            if (rep && typeof rep === 'object') {
                length = rep.length;
                for (i = 0; i < length; i += 1) {
                    k = rep[i];
                    if (typeof k === 'string') {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            } else {
                for (k in value) {
                    if (Object.hasOwnProperty.call(value, k)) {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            }
            v = partial.length === 0 ? '{}' :
                gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
                        mind + '}' : '{' + partial.join(',') + '}';
            gap = mind;
            return v;
        }
    }
    if (typeof JSON.stringify !== 'function') {
        JSON.stringify = function (value, replacer, space) {         
            var i;
            gap = '';
            indent = '';
            if (typeof space === 'number') {
                for (i = 0; i < space; i += 1) {
                    indent += ' ';
                }
            } else if (typeof space === 'string') {
                indent = space;
            }
            rep = replacer;
            if (replacer && typeof replacer !== 'function' &&
                    (typeof replacer !== 'object' ||
                     typeof replacer.length !== 'number')) {
                throw new Error('JSON.stringify');
            }
            return str('', {'': value});
        };
    }
    if (typeof JSON.parse !== 'function') {
        JSON.parse = function (text, reviver) {
            var j;
            function walk(holder, key) {
                var k, v, value = holder[key];
                if (value && typeof value === 'object') {
                    for (k in value) {
                        if (Object.hasOwnProperty.call(value, k)) {
                            v = walk(value, k);
                            if (v !== undefined) {
                                value[k] = v;
                            } else {
                                delete value[k];
                            }
                        }
                    }
                }
                return reviver.call(holder, key, value);
            }
            cx.lastIndex = 0;
            if (cx.test(text)) {
                text = text.replace(cx, function (a) {
                    return '\\u' +
                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
                });
            }
            if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
                j = eval('(' + text + ')');
                return typeof reviver === 'function' ?
                    walk({'': j}, '') : j;
            }
            throw new SyntaxError('JSON.parse');
        };
    }
}());
