/*
 * JavaScript file jquery.google-news-search.js v0.1 last modified 11/02/07
 */

(function(jQuery) {
	var settings, self, content, width, newsTags, control, currentID, cookies, newsSearch, searchControl, deleteButton;
	jQuery.fn.googleNewsSearch = function() {
		self = this;
		var args = jQuery.makeArray(arguments),
			options = jQuery.isPlainObject(args[args.length - 1]) ? args.pop() : {},
			keywords = jQuery.trim(args.join(' '));
			
		settings = jQuery.extend({}, jQuery.fn.googleNewsSearch.defaults, options);
		currentID = 1000;
		newsTags = [];
		cookies = getCookie('news-tags');
		cookies = cookies != '' ? jQuery.trim(cookies).split(',') : [];
		cookies = unique( cookies.concat(settings.defaultKeywords || []) );
		
		return this.each(function() {
			jQuery(this)
			.append(
				content = jQuery('<div />', { id: 'news_content' }).css({ fontSize: settings.baseFontSize })
				.append(
					jQuery('<div />', { id: 'news_top' })
					.append( jQuery('<span />', { id: 'news_loading', 'class': 'news_loading', html: '読み込み中……' }) )
					.append(
						control = jQuery('<form />', { id: 'news_search_form', 'class': 'news_search_form' })
						.append(jQuery('<label />', { id: 'news_label', htmlFor: 'news_keyword', html: '追加キーワード ' }))
						.append(jQuery('<input />', { id: 'news_keyword', name: 'news_keyword' }))
					)
				)
				.append(
					jQuery('<form />', { id: 'news_tags_form', 'class': 'news_tags_form' })
					.append( newsTags[newsTags.length] = jQuery('<div />', { 'class': 'news_tags' }) )
				)
				.append( jQuery('<div />', { 'class': 'clear_float' }) )
			);
			
			deleteButton = jQuery('<button />', { id: 'delete_news_tag', html: 'タグ削除' });
			
			if (cookies.length) {
				jQuery.each(cookies, function(index, value) {
					addNewsTag(value);
				});
			}
			
			newsSearch = new google.search.NewsSearch();
			
			newsSearch.setSearchCompleteCallback(this, googleNewsSearchComplete, null);
			newsSearch.setResultSetSize(settings.size);
			newsSearch.execute(keywords);
			
			jQuery('#news_search_form').submit(function(event) {
				event.preventDefault();
				
				var value = jQuery('#news_keyword').val();
				jQuery('#news_loading').html('読み込み中……').show();
				
				addNewsTag(value);
				newsSearch.execute(value);
				jQuery('#news_keyword').autocomplete('close');
			});
			
			deleteButton.button({
				icons: { primary: 'ui-icon-closethick' },
				text: false
			})
			.click(function(event) {
				event.preventDefault();
				var element = jQuery(this).closest('label').prev('input'),
					parent = element.parent('div'),
					pIndex = parent.index();
				
				if (element.length) {
					var v = element.val();
					cookies = jQuery.map(cookies, function(value, index) {
						if (v == value) return null;
						else return value;
					});
					setCookie('news-tags', cookies.join(','), getExpDate(30, 0, 0));
					
					deleteButton.detach();
					
					element.button('destroy')
					.next('label').andSelf().remove();
					
					if (!parent.children().length) {
						parent.remove();
						newsTags = jQuery.map(newsTags, function(element, index) {
							if (index == pIndex) return null;
							else return element;
						});
					}
					
					jQuery('.news_tags').buttonset();
				}
			});
			
			jQuery('#news_keyword').autocomplete({
				delay: 100,
				source: function(request, response) {
					jQuery.getJSON(
						'http://suggestqueries.google.com/complete/search?callback=?',
						{
							hl: 'ja',
							q: request.term
						},
						function(data) {
							if (jQuery.isArray(data)) {
								response( jQuery.map(data[1], function(item, index) {
									if (index !== 0) return item[0];
								}) );
							}
						}
					);
				},
				minLength: 1,
				select: function(event, ui) {
					var label = ui.item.label;
					jQuery('#news_loading').html('読み込み中……').show();
					
					addNewsTag(label);
					newsSearch.execute(label);
				},
				open: function() {
					jQuery( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
				},
				close: function() {
					jQuery( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
				}
			}).focus();
			
		});
	};
	
	jQuery.fn.googleNewsSearch.defaults = {
		defaultKeywords: ['秋田県', '白神', 'なまはげ'],
		size: 8,
		baseFontSize: '12px'
	};
	
	function googleNewsSearchComplete() {
		var i, nTime = new Date().getTime();
		if (newsSearch.results && newsSearch.results.length > 0) {
			jQuery('#news_loading').html(newsSearch.results.length + ' 件のニュースがヒットしました');
			jQuery('#news_branding').remove();
			content.children('div.news_article').remove();
			
			for (i = 0, l = newsSearch.results.length; i < l; i++) {
				var news = newsSearch.results[i],
					url = decodeURIComponent(news.url),
					publisher = news.publisher,
					pDate = new Date(news.publishedDate),
					diff = nTime - pDate.getTime(),
					pBefore = diff / (1000 * 60 * 60 * 24) >= 30 ? Math.floor(diff / (1000 * 60 * 60 * 24 * 30)) + 'ヶ月前' :
						diff / (1000 * 60 * 60) >= 24 ? Math.floor(diff / (1000 * 60 * 60 * 24)) + '日前' :
						diff / (1000 * 60 * 60) >= 1 ? Math.floor(diff / (1000 * 60 * 60)) + '時間前' : diff / (1000 * 60) >= 1 ?
						Math.floor(diff / (1000 * 60)) + '分前' : Math.floor(diff / 1000) + '秒前',
					article;
				
				content.append( article = jQuery('<div />', { 'class': 'news_article' }) );
				if (news.image && i === 0) {
					article
					.append(
						jQuery('<a />', { href: url })
						.append(
							jQuery('<img />', {
								css: { 'float': 'left' },
								width: news.image.tbWidth,
								height: news.image.tbHeight,
								src: news.image.url
							})
						)
					);
				}
				
				article
				.append(
					jQuery('<a />', { href: url, html: news.title, data: { index: i } })
					.mouseover(function() {
						//console.log(jQuery(this).data('index'));
					})
				)
				.append(
					jQuery('<span />', { 'class': 'news_info', html: pBefore/* + ' ' + pDate.toLocaleString()*/ + ' - ' + publisher })
				);
				
				if (news.clusterUrl) {
					var clusterUrl = decodeURIComponent(news.clusterUrl);
					article
					.append(
						jQuery('<a />', { href: clusterUrl, 'class': 'news_relevance', html: '関連記事' })
					);
				}
				article.append( jQuery('<br />' ) );
				
				if (i === 0) {
					article.append( jQuery('<p />', { html: news.content }) );
				}
			}
			content.append( jQuery('<div />', { id: 'news_branding' }) );
			google.search.Search.getBranding('news_branding');
		}
		else {
			jQuery('#news_loading').html('ニュースが見つかりませんでした').show();
		}
	}
	
	function addNewsTag(value) {
		if (value == '') return;
		
		var radioID = 'news_' + currentID,
			width = content.width(),
			tIndex = -1,
			input, label;
		
		input = jQuery('<input />', { id: radioID, name: 'news_tags', type: 'radio', value: value });
		label = jQuery('<label />', { htmlFor: radioID, html: value })
		.click(function() {
			jQuery('#news_loading').html('読み込み中……').show();
			deleteButton.detach();
			jQuery(this).children('span').append(deleteButton);
			newsSearch.execute(value);
		});
		
		deleteButton.detach();
		jQuery.each(newsTags, function(index, element) {
			element.append(input).append(label);
			jQuery('.news_tags').buttonset();
			
			if (element.width() + 35 <= width) {
				tIndex = index;
				return false;
			}
			input.next().andSelf().detach();
		});
		
		if (tIndex == -1) {
			jQuery('#news_tags_form').append(
				newsTags[newsTags.length] = jQuery('<div />', { 'class': 'news_tags' })
				.append(input).append(label)
			);
			jQuery('.news_tags').buttonset();
		}
		
		cookies.push(value);
		cookies = unique(cookies);
		setCookie('news-tags', cookies.join(','), getExpDate(30, 0, 0));
		
		currentID++;
		
		return radioID;
	}
	
	function unique(array) {
		var storage = {}, uniqueArray = [], i, value;
		for (i = 0; i < array.length; i++) {
			value = array[i];
			if (!(value in storage)) {
				storage[value] = true;
				uniqueArray.push(value);
			}
		}
		return uniqueArray;
	}
	
	/* クッキー管理用ユーティリティ */
	function getExpDate(days, hours, minutes) {
		var expDate = new Date();
		if (typeof days == 'number' && typeof hours == 'number' && typeof minutes == 'number') {
			expDate.setDate(expDate.getDate() + parseInt(days));
			expDate.setHours(expDate.getHours() + parseInt(hours));
			expDate.setMinutes(expDate.getMinutes() + parseInt(minutes));
			return expDate.toUTCString();
		}
	}
	
	function getCookieVal(offset) {
		var endstr = document.cookie.indexOf(';', offset);
		if (endstr == -1) {
			endstr = document.cookie.length;
		}
		return unescape(document.cookie.substring(offset, endstr));
	}
	
	function getCookie(name) {
		var arg = name + '=';
		var alen = arg.length;
		var clen = document.cookie.length;
		var i = 0;
		while (i < clen) {
			var j = i + alen;
			if (document.cookie.substring(i, j) == arg) {
				return getCookieVal(j);
			}
			i = document.cookie.indexOf(' ', i) + 1;
			if (i === 0) break;
		}
		return '';
	}
	
	function setCookie(name, value, expires, path, domain, secure) {
		document.cookie = name + '=' + escape(value) +
			((expires) ? '; expires=' + expires : '') +
			((path) ? '; path=' + path : '') +
			((domain) ? '; domain=' + domain : '') +
			((secure) ? '; secure=' + secure : '');
	}
	
	function deleteCookie(name, path, domain) {
		if (getCookie(name)) {
			document.cookie = name + '=' +
				((path) ? '; path=' + path : '') +
				((domain) ? '; domain=' + domain : '') +
				'; expires=Thu, 01-Jan-70 00:00:01 GMT';
		}
	}
})(jQuery);
