/**
 * @provides nxj.preinit
 */

/**
 * preinit
 *
 * @class NXJ
 * @static
 * @access private
 */
if(!window.NXJ) {
    NXJ = {
        apiKey : null,
        locale : 'en_US',
        domain : {
            api : window.location.protocol + '//api.oo.com',
            www : window.location.protocol + '//www.oo.com'
        },

        browserType : null,
        isAuthenticated : false,
        logging : false,

        create : function(name) {
            var node = window.NXJ;
            var packages = name ? name.split('.') : [];
            var length = packages.length;
            for(var i=0; i<length; i++) {
                if(!node[packages[i]]) {
                    node[packages[i]] = {};
                }
                node = node[packages[i]];
            }

            return node;
        },

        load : function(name, value) {
            var node = NXJ.create(name);

            for(var key in value) {
                node[key] = value[key];
            }

            if(node.constructor) {
                node.constructor();
            }
        },

        log : function(message) {
            if (NXJ.logging) {
                if (window.Debug && window.Debug.writeln) {
                    window.Debug.writeln(message);
                } else if (window.console) {
                    window.console.log(message);
                } else {
                    alert(message);
                }
            }
        }
    };
}
/**
 * @provides nxj.init
 * @requires nxj.preinit
 *           nxj.cookie
 *           nxj.util
 */

/**
 * This is the top level for all the public APIs.
 *
 * @class NXJ
 * @static
 * @access public
 */
NXJ.load(null, {
    init : function(options) {

        for(var option in options) {
            NXJ[option] = options[option];
        }

        NXJ.browserType = NXJ.util.getBrowserType();
        NXJ.isAuthenticated = NXJ.cookie.getCookie('sid');
    }
});
/**
 * @provides nxj.utils
 * @requires nxj.preinit
 */

/**
 *
 * @class NXJ.utils
 * @static
 * @access private
 */
NXJ.load('util', {

    getBrowserType : function() {
        if (!NXJ.browserType) {
            var userAgent = window.navigator.userAgent.toLowerCase();
            var keys  = ['msie', 'firefox', 'safari', 'gecko'];
            var names = ['ie',   'mozilla', 'safari', 'mozilla'];
            var i=0;
            for (i = 0; i < keys.length; i++) {
                if (userAgent.indexOf(keys[i]) >= 0) {
                    NXJ.browserType = names[i];
                    break;
                }
            }
        }
        return NXJ.browserType;
    },

    echo : function(value) {
        return value;
    }
});

NXJ.load('request', {
	getParam : function(name, defaultValue)
	{
	  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
	  var regexS = "[\\?&]"+name+"=([^&#]*)";
	  var regex = new RegExp( regexS );
	  var results = regex.exec( window.location.href );
	  if( results == null )
	    return defaultValue;
	  else
	    return results[1];
	}
});

/**
 * @provides nxj.window
 * @requires nxj.preinit
 */

/**
 *
 * @class NXJ.window
 * @static
 * @access private
 */
NXJ.load('window', {
    open : function(url, name, options) {
    	var w,h,x,y;
        if (NXJ.browserType === 'ie') {
            w = document.body.clientWidth;
            h = document.body.clientHeight;
            x = window.screenTop;
            y = window.screenLeft;
        } else {
            w = window.innerWidth;
            h = window.innerHeight;
            x = window.screenX;
            y = window.screenY;
        }

        var leftPos = ((w-450)/2)+y;
        var topPos = ((h-450)/2)+x;

        view = window.open(url, name, options + ',top='+topPos+',left='+leftPos);

        if (window.focus) {
            view.focus();
        }
        return false;
    }
});
/**
 * @provides nxj.ui
 * @requires nxj.preinit
 */

/**
 *
 * @class NXJ.ui
 * @static
 * @access private
 */
NXJ.load('ui', {
    createIFrame : function(options) {
        var tag = document.createElement('iframe');

        tag.id = options.id;
        tag.name = options.id;
        tag.style.border = 'none';
        tag.style.overflow = 'hidden';
        tag.frameBorder = '0';
        tag.allowtransparency='true';
        tag.src = options.url;
        tag.scrolling = 'no';

        if (options.className) {
            tag.className = options.className;
        }
        if (options.height) {
            tag.style.height = options.height + 'px';
        }
        if (options.width) {
            tag.style.width = options.width + 'px';
        }

        options.root = document.getElementById(options.container);
        options.root.appendChild(tag);
    }
});

/**
 * @provides nxj.event
 * @requires nxj.preinit
 */

/**
 * Event handling mechanism for globally named events.
 *
 * @static
 * @class NXJ.event
 */
NXJ.load('event', {
    subscribers : {},

    subscribe : function(name, callback) {
        if(!this.subscribers[name]) {
            this.subscribers[name] = [callback];
        } else {
            this.subscribers[name].push(callback);
        }
    },

    unsubscribe : function(name, callback) {
        for(node in this.subscribers) {
            for(values in node) {
                node[value] = null;
            }
        }
    },

    clear: function(name) {
        delete this.subscribers[name];
    },

    raise : function() {
        var args = Array.prototype.slice.call(arguments);
        var name = args.shift();

        if(this.subscribers[name]) {
            for(var i=0; i<this.subscribers[name].length; i++) {
                this.subscribers[name][i](args);
            }
        }
    }
});

NXJ.load('search.autocomplete', {
	input: null,	
	button: null,
	currentValue: 'Search Stores',
	selectedIndex: -1,
	suggestions: [],	
	groups: {},
	handle: null,
	list : "panda-list-container",
	listStyle: {
		top: 0,
		left: 0,
		width: 400,
		offset: 'right'
	},			

	init: function(options) {
		for(var option in options) {
            NXJ.search.autocomplete[option] = options[option];
        }
		
		var term = NXJ.request.getParam('panda-search-term', null);
		if(term) {
			term = unescape(term).evalJSON(true);
			this.suggestions.push(term);
			this.selectedIndex = 0;
		} else {
			term = {"name":this.currentValue};
		}
		
		var div = new Element('div', {id: this.list});
		document.body.appendChild(div);
		
		this.input = $(this.input);
		this.list = $(this.list);
		this.button = $(this.button);
		
		this.currentValue = term.name;
		this.input.setValue(this.currentValue);
		this.input.observe('blur', this.onBlur.bind(this));
		this.input.observe('focus', this.onFocus.bind(this));
		this.input.setAttribute('autocomplete','off');
		this.button.observe('click', this.select.bind(this));
		
		this.enable();				
	},
	
	activate: function() {
		this.setListStyle();
		this.input.setValue('');
		this.input.observe('keydown', this.onKeyPress.bind(this));
	},
	
	deactivate: function() {
		this.hide();
		this.input.stopObserving('keydown');
		this.input.setValue('Search Stores');
		
	},
	
	setListStyle: function() {
	    var offset = this.input.cumulativeOffset();
	    this.list.setStyle(
	    	{ 
	    		top: (offset.top + this.listStyle.top) + 'px', 
	    		left: (offset.left + this.listStyle.left) + 'px', 
	    		width: this.listStyle.width + 'px'
	    	}
	     );
	},

	onFocus: function() {
		this.activate();		
	},
	
	onBlur: function() {		
		setTimeout(this.deactivate.bind(this), 500);
	},
	
	onKeyPress: function(e) {
		switch (e.keyCode) {
			case Event.KEY_ESC:
				this.hide();
				break;
		  case Event.KEY_RETURN:
			if (this.selectedIndex === -1) {
				this.hide();
				return;
			}
			this.select();
			this.setListStyle();
			break;
		  case Event.KEY_UP:
			this.moveUp();
			break;
		  case Event.KEY_DOWN:
			this.moveDown();
			break;
		  default:
			return;
		}
		Event.stop(e);
	},			
	
	onMouseClick: function(index) {
		this.selectedIndex = index;
		this.select();
	},
	
	getSuggestions: function() {
		var value = this.input.getValue();
		if(value === 'Search Stores') {
				return;
		}
		if(this.currentValue !== value) {
			this.currentValue = value;
			if(this.currentValue.length > 1) {				
	            new Ajax.Request('/panda/autocomplete', {
	                method : 'get',
	                parameters : {
	                    'version' : '1.0',
	                    'data' : this.currentValue
	                },
	                onSuccess :this.processResponse.bind(this),
	                onFailure : function (transport) {
	                }
	            });
			} else {
				this.hide();
			}					
		}
	},
	
	processResponse: function(transport) {
        this.suggestions = transport.responseText.evalJSON(true);    
        this.suggestions.splice(0,0,
			{"name":this.currentValue, "value":0, "type":"Search", "pageIndex":0}
		);
		this.selectedIndex = 0;
		this.renderList();
		this.selectListItem();
		this.list.setStyle({'display':'block'});
	},
	
	renderList: function() {		
		var groups = {"Search":[],"Category":[],"Stores":[],"More Stores":[]};		
		var regex = new RegExp(this.currentValue.match(/[\s\w]+/g), 'gi');
		
		for(var i=0; i<this.suggestions.length; i++) {					
			if(this.suggestions[i].type === 'Merchant') {						
				if(!this.suggestions[i].name.match(regex)) {
					this.suggestions[i].type = 'More Stores';
				} else {
					this.suggestions[i].type = 'Stores';
				}
			}			
			groups[this.suggestions[i].type].push(this.suggestions[i]);
		}		

		
		this.suggestions = [];
		var element = '<table id="panda-list">';	

		if(this.listStyle.offset === 'right') {
			element += this.renderGroupRight(groups, regex);
		} else {
			element += this.renderGroupLeft(groups, regex);
		}		
		
		element += '</table>';
		this.list.update(element);
	},
	
	renderGroupLeft: function(groups, regex) {
		var element = '';
		for(var group in groups) {
			if(groups[group].length > 0) {
				element += '<tr>';
				element += '<td class="panda-group panda-group-right" valign="top">';
				element += '<div>'	+ group	+ '</div>';
				element += '</td>';
				element += '<td valign="top" class="panda-item">';
				element += this.renderGroupItems(groups[group], regex);
				element += '</td>';
				element += '</tr>';
			}
		}		
		
		return element;
	},
	
	renderGroupRight: function(groups, regex) {
		var element = '';
		for(var group in groups) {
			if(groups[group].length > 0) {
				element += '<tr><td valign="top" class="panda-item">';
				element += this.renderGroupItems(groups[group], regex);
				element += '</td><td class="panda-group panda-group-left" valign="top">';
				element += '<div>'	+ group	+ '</div>';
				element += '</td></tr>';
			}
		}		
		
		return element;
	},
	
	renderGroupItems: function(group, regex) {
		var element = '';
		for(var j=0; j<group.length; j++) {
			this.suggestions.push(group[j]);
			var index = this.suggestions.length - 1;
			group[j].name = group[j].name.replace('<', '&lt;');
			group[j].name = group[j].name.replace('<', '&lt;');
			element += '<div id="panda-list-item-' + (index) + '" index="' + (index) 
				+ '" onclick="NXJ.search.autocomplete.onMouseClick(' + index 
				+ ')" onmouseover="this.className=\'panda-selected-item\'" onmouseout="this.className=\'\'">'
				+ this.highlite(regex, group[j].name)
				+ '</div>';
		}
		return element;
	},
	
	highlite: function(regex, value) {
		return value.replace(regex, function(match){
			return '<span>' + match + '</span>';
		});
	},
	
	moveUp: function() {
		if(this.selectedIndex <= 0) {
			return;
		}
		this.selectedIndex--;
		this.selectListItem();
	},
	
	moveDown: function() {
		if(this.selectedIndex >= this.suggestions.length - 1) {
			return;
		}
		this.selectedIndex++;
		this.selectListItem();
	},
	
	selectListItem: function() {
		for(var i=0; i<this.suggestions.length; i++) {
			$('panda-list-item-' + i).className = '';	
		}
		$('panda-list-item-' + this.selectedIndex).className = 'panda-selected-item';
	},
	
	getElement: function(event) {
		if(event.currentTarget) {
			return event.currentTarget; 
		} else if(event.toElement) {
			return event.toElement;
		} else if(event.srcElement) {
			return event.srcElement;	
		}
		
		return null;
	},
	
	select: function() {
		this.matchTerm();
		if(this.selectedIndex === 0) {
			window.location.href = '/panda/result/?panda-search-match=false&panda-search-term=' 
				+ escape('{"name":"' + this.input.getValue() + '", "value":0, "type":"Search", "pageIndex":0}');			
		} else {
			window.location.href = '/panda/result/?panda-search-match=true&panda-search-term='
				+ escape(Object.toJSON(this.suggestions[this.selectedIndex]));
		}
		this.hide();
		this.disable();		
	},
	
	matchTerm: function() {
		if(this.suggestions.length > 1) {
			if(this.currentValue.toLowerCase() === this.suggestions[1].name.toLowerCase()) {
				this.selectedIndex = 1;
			}
		}
	},	
	
	hide: function() {
		this.selectedIndex = -1;
		this.list.hide();
	},
	
	enable: function() {
		this.handle = setInterval(this.getSuggestions.bind(this), 250);
	},
	
	disable: function() {
		clearInterval(this.handle);
	}
});

