/* vim: set enc=utf8 ts=4 fdm=marker: */
/***************************************************************
 * Firefly Navigator
 * COPYRIGHT (C) 2007 MADDY PROJECT ALL RIGHTS RESERVED.
 * $Id: firefly.js 216 2007-09-26 17:20:18Z  $
 ***************************************************************/

var Firefly = {

	// content stock {{{
	Stock: {
		// toolbar
		keywordField:	null,
		currentKeyword:	null,
		// sidebar
		sidebarTabs:	null,
		searchTab:		null,
		stickyTab:		null,
		searchTree:		null,
		stickyTree:		null,
		draggingText:	null,
		// viewer
		viewerTabs:		null,
		thumbTemplate:	null,

		// void clearStock() {{{
		clear: function(stock) {
			if(stock !== null) {
			//	delete stock;
				stock = null;
			}
		}
		// }}}
	},
	// }}}

	// void showError() {{{
	showError: function(msg, callback) {
		Ext.MessageBox.alert('エラー', msg, callback);
	},
	// }}}
	// void showHome() {{{
	showHome: function() {
		Firefly.selectViewerTab(null, 'ViewerTabs_Home', 'ホーム', '?m=get_home_contents', true);
	},
	// }}}
	// void showHelp() {{{
	showHelp: function() {
		Firefly.selectViewerTab(null, 'ViewerTabs_Help', 'ヘルプ', '?m=get_help_contents');
	},
	// }}}
	// void showSupport() {{{
	showSupport: function() {
		Firefly.selectViewerTab(null, 'ViewerTabs_Support', 'サポート', '?m=get_support_contents');
	},
	// }}}

	// string htmlescape() {{{
	htmlescape: function(str) {
		return str.replace(/</, '&lt;').replace(/>/, '&gt;').replace(/"/, '&quot;').replace(/'/, '&rsquo;');
	},
	// }}}

	// Ext.BorderLayout getPageLayoutConfig() {{{
	getPageLayoutConfig: function() {
		return new Ext.BorderLayout(document.body, {
			// header
			north: {
				split:			false,
				initialSize:	40,
				autoScroll:		false,
				titlebar:		false
			},
			// footer
			south: {
				split:			false,
				initialSize:	48,
				autoScroll:		false,
				titlebar:		false
			},
			// sidebar
			west: {
				split:			true,
				initialSize:	260,
				minSize:		16,
				maxSize:		480,
				titlebar:		true,
				collapsible:	true,
				animate:		true,
				autoScroll:		false,
				tabPosition:	'top',
				closeOnTab:		false
			},
			// viewer
			center: {
				titlebar:		false,
				autoScroll:		false,
				closeOnTab:		true
			}
		});
	},
	// }}}
	// Ext.Toolbar createToolbar() {{{
	createToolbar: function() {
		Firefly.Stock.keywordField = new Ext.form.TextField({
			id:			'Toolbar_Keyword',
			inputType:	'text',
			firldLabel:	'',
			name:		'q',
			value:		'',
			maxLength:	255
		});
		var searchButton = new Ext.Toolbar.Button({
			id:			'Toolbar_SearchButton',
			text:		'検索',
			handler:	function() {
							Firefly.loadRelatedKeywordsProxy(Firefly.Stock.keywordField.getValue());
						}
		});
		var popularButton = new Ext.Toolbar.Button({
			id:			'Toolbar_PopularButton',
			text:		'人気キーワード',
			handler:	Firefly.loadPopularKeywords
		});
		var toolbar = new Ext.Toolbar('Toolbar');
		toolbar.addField(Firefly.Stock.keywordField);
		toolbar.addButton(searchButton);
		toolbar.addButton(popularButton);
		Firefly.Stock.keywordField.on('specialkey', function(field, e) {
			if(e.getKey() == e.ENTER) {
				Firefly.loadRelatedKeywordsProxy(field.getValue());
			}
		});
		//
		// drop text from tree
		//
		Firefly.createDropTarget('Toolbar', function(dom, e) {
			if(Firefly.Stock.draggingText) {
				Firefly.Stock.keywordField.setValue(Firefly.Stock.draggingText);
			}
			return true;
		});
		return toolbar;
	},
	/// }}}
	// void createDropTarget() {{{
	createDropTarget: function(id, callback) {
		Ext.get(id).on('mouseup', callback);
		Ext.get(id).on('mouseover', function(dom, e) {
			if(Firefly.Stock.draggingText) {
				$('div[@class=x-dd-drop-icon]').css('background-image', 'url(/ext/resources/images/default/dd/drop-yes.gif)');
			}
		});
		Ext.get(id).on('mouseout', function(dom, e) {
			if(Firefly.Stock.draggingText) {
				$('div[@class=x-dd-drop-icon]').css('background-image', 'url(/ext/resources/images/default/dd/drop-no.gif)');
			}
		});
	},
	// }}}
	// void initializePageLayout() {{{
	initializePageLayout: function() {
		var pageLayout = Firefly.getPageLayoutConfig();
		var toolbar = Firefly.createToolbar();
		pageLayout.beginUpdate();
			pageLayout.add('north', new Ext.ContentPanel('HeaderPane', 'North'));
			pageLayout.add('south', new Ext.ContentPanel('FooterPane', 'South'));
			pageLayout.add('west', new Ext.ContentPanel('SidebarPane', {
				title:		'キーワードブラウザ',
				toolbar:	toolbar,
				fitToFrame:	true
			}));
			pageLayout.add('center', new Ext.ContentPanel('ViewerPane', {
				title:		'ビューア'
			}));
		pageLayout.endUpdate();
		//
		// drop text from tree
		//
		Firefly.createDropTarget('ViewerPane', function(dom, e) {
			if(Firefly.Stock.draggingText) {
				Firefly.loadRelatedImages(null, Firefly.Stock.draggingText);
			}
			return true;
		});
	},
	// }}}
	// void initializeSidebar() {{{
	initializeSidebar: function() {
		Firefly.Stock.sidebarTabs = new Ext.TabPanel('SidebarTabs', {
			resizeTabs:			true,
			minTabWidth:		20,
			preferredTabWidth:	90
		});
		Firefly.Stock.searchTab = Firefly.Stock.sidebarTabs.addTab('SidebarTabs_Search', '検索');
		Firefly.Stock.stickyTab = Firefly.Stock.sidebarTabs.addTab('SidebarTabs_Sticky', 'Sticky検索');
		Firefly.Stock.sidebarTabs.on('tabchange', Firefly.onSidebarTabChanged);
		Firefly.refreshTab(Firefly.Stock.stickyTab, '検索結果はありません');
		Firefly.refreshTab(Firefly.Stock.searchTab, '検索結果はありません');
	},
	// }}}
	// void initializeViewer() {{{
	initializeViewer: function() {
		//
		// viewer tabs
		//
		Firefly.Stock.viewerTabs = new Ext.TabPanel('ViewerTabs', {
			resizeTabs:			true,
			minTabWidth:		20,
			preferredTabWidth:	130
		});
		//
		// loading template
		//
		// {{{
		Firefly.Stock.thumbTemplate = new Ext.Template(
			'<div class="Thumbnail">' +
				'<div class="Thumbnail_Image">' +
					'<img src="{thumbnail}" title="{title}" alt="{title}" />' +
				'</div>' +
				'<div class="Thumbnail_Title">' +
					'{title:ellipsis(16)}' +
				'</div>' +
				'<div class="Detail" style="display:none;">' +
					'<div class="Detail_Image">' +
						'<img src="{source}" title="{title}" alt="{title}" />' +
					'</div>' +
					'<div class="Detail_Info">' +
						'<table>' +
							'<tr class="Detail_Info_Title"><th>名前</th><td><a href="{owner}" title="{title}" target="_blank">{title}</a></td></tr>' +
							'<tr class="Detail_Info_Description"><th>説明</th><td>{description:trim}</td></tr>' +
							'<tr class="Detail_Info_Format"><th>種別</th><td>{format}</td></tr>' +
							'<tr class="Detail_Info_Size"><th>サイズ</th><td>{size} ({width}x{height})</td></tr>' +
							'<tr class="Detail_Info_Distributer"><th>情報元</th><td><a href="{service}" title="{distributer:capitalize}"><img src="' + String.format(distIconFormat, '{distributer:lowercase}') + '" alt="{distributer:capitalize}" /></a></td></tr>' +
						'</table>' +
					'</div>' +
				'</div>' +
			'</div>');
		Firefly.Stock.thumbTemplate.compile();
		// }}}
	},
	// }}}

	// int getSidebarContentHeight() {{{
	getSidebarContentHeight: function() {
		return Ext.get('SidebarTabs').findParent('div.x-layout-panel-body', 10, true).getHeight(true) -
					Ext.get('Toolbar').getHeight(true) -
					Ext.get('SidebarTabs').child('div.x-tabs-wrap').getHeight(true) -
					Ext.get(Firefly.getTabCaptionId(Firefly.getSidebarActiveTab())).getHeight(true) -
					4;// against IE bugs
	},
	// }}}
	// int getViewerContentHeight() {{{
	getViewerContentHeight: function() {
		return Ext.get('ViewerTabs').findParent('div.x-layout-panel-body', 10, true).getHeight(true) -
					Ext.get('ViewerTabs').child('div.x-tabs-wrap').getHeight(true) -
					4;// against IE bugs
	},
	// }}}
	// string getTabCaptionId() {{{
	getTabCaptionId: function(tab) {
		return String.format('TabCaption_{0}', tab.id);
	},
	// }}}
	// string getTabContentId() {{{
	getTabContentId: function(tab) {
		return String.format('TabContent_{0}', tab.id);
	},
	// }}}
	// void refreshTab() {{{
	refreshTab: function(tab, caption) {
		//
		// clear tab content
		//
		var captionId = Firefly.getTabCaptionId(tab);
		var contentId = Firefly.getTabContentId(tab);
		tab.setContent(String.format('<div id="{0}"></div><div id="{1}"></div>', captionId, contentId));
		tab.activate();
		//
		// attach new caption
		//
		if(caption) {
			var toolbar = new Ext.Toolbar(captionId);
			toolbar.addButton({ text: Firefly.htmlescape(caption) });
		}
//		Ext.get(contentId).setHeight(Firefly.getSidebarContentHeight());
	},
	// }}}
	// bool isStickyMode() {{{
	isStickyMode: function() {
		return (Firefly.getSidebarActiveTab() == Firefly.Stock.stickyTab);
	},
	// }}}
	// Ext.TabPanelItem getSidebarActiveTab() {{{
	getSidebarActiveTab: function() {
		return Firefly.Stock.sidebarTabs.getActiveTab();
	},
	// }}}
	// Ext.TreeNode getSidebarActiveTree() {{{
	getSidebarActiveTree: function() {
		return Firefly.isStickyMode() ? Firefly.Stock.stickyTree : Firefly.Stock.searchTree;
	},
	// }}}
	// void setSticky() {{{
	setSticky: function(node) {
		var c = node.childNodes;
		for(var idx = 0; idx < c.length; idx++) {
			c[idx].setText(node.attributes.text + ' ' + c[idx].attributes.text);
		}
	},
	// }}}
	// Ext.TreeNode createSidebarTree() {{{
	createSidebarTree: function(tab, dataUrl, rootText) {
		var loader = new Ext.tree.TreeLoader({
			dataUrl: dataUrl
		});
		loader.on('load', function(treeLoader, node) {
			if(Firefly.isStickyMode()) {
				Firefly.setSticky(node);
			}
			// against IE bugs [begin]
			var paddingNode = $('#Padding_' + Firefly.getTabContentId(tab));
			if(paddingNode.length < 1) {
				$('#'+Firefly.getTabContentId(tab)).append('<div id="' + 'Padding_' + Firefly.getTabContentId(tab) + '" style="visivility:hidden; height:32px;" />');
			}
			// against IE bugs [end]
		});
		loader.on('beforeload', function(treeLoader, node) {
			this.baseParams.q = node.attributes.text;
		});
		var tree = new Ext.tree.TreePanel(Firefly.getTabContentId(tab), {
			animate:			true,
			containerScroll:	true,
			rootVisible:		true,
			loader:				loader,
			enableDrag:			true,
			enableDrop:			false,
			setModel:			true
		});
		var rootNode = new Ext.tree.AsyncTreeNode({
			id:			String.format('{0}_Root', tab.id),
			text:		Firefly.htmlescape(rootText),
			leaf:		false,
			extanped:	true
		});
		tree.setRootNode(rootNode);
		tree.render();
		Ext.get(Firefly.getTabContentId(tab)).applyStyles('height:' + Firefly.getSidebarContentHeight() + 'px;');
		tree.root.expand(false, true);
		tree.on('click', Firefly.loadRelatedImages);
		tree.on('startdrag', function(panel, node, e) {
			Firefly.Stock.draggingText = node.text;
		});
		tree.on('enddrag', function(panel, node, e) {
			Firefly.Stock.draggingText = null;
		});
		return tree;
	},
	// }}}
	// void showImageDetailDialog() {{{
	showImageDetailDialog: function(node) {
		var detail = new Ext.Element(node).child('div.Detail');
		var detailDialog = new Ext.BasicDialog('DetailDialog', {
			width:			640,
			height:			480,
			minWidth:		150,
			minHeight:		120,
			modal:			true,
			resizable:		false,
			shadow:			true,
			animateTarget:	node,
			autoCreate:		true,
			autoScroll:		true,
			buttonAlign:	'center',
			title:			'画像の情報'
		});
		detailDialog.addButton('別ウィンドウで開く', function() {
			var url = $(detail.child('img').dom).attr('src');
			var title = $(detail.child('img').dom).attr('title');
			// against IE bugs [begin]
			if(navigator.userAgent.match(/MSIE/)) {
				title = '';
			}
			// against IE bugs [end]
			window.open(url, title, "menubar=no,toolbar=no,statusbar=yes,directories=no,location=yes,scrollbars=yes,resizeable=yes");
		});

		detailDialog.addButton('閉じる', function() {
			detailDialog.hide();
			detailDialog.destroy();
		});

		var layout = new Ext.BorderLayout(detailDialog.body.id, {
			east: {
				split:			false,
				initialSize:	200,
			//	minSize:		16,
			//	maxSize:		400,
				titlebar:		true,
				collapsible:	true,
				autoScroll:		true
			},
			south: {
				split:			false,
				initialSize:	0,
				titlebar:		false
			},
			center: {
				titlebar:		true,
				collapsible:	false,
				autoScroll:		true
			}
		});
		var imgPane = new Ext.ContentPanel('DetailDialog_Image', {
			title:		'画像',
			fitToFrame:	true
		});
		imgPane.setContent(detail.child('div.Detail_Image').dom.innerHTML);
		var infoPane = new Ext.ContentPanel('DetailDialog_Info', {
			title:		'詳細',
			fitToFrame:	true
		});
		infoPane.setContent(detail.child('div.Detail_Info').dom.innerHTML);
		layout.beginUpdate();
			layout.add('east', infoPane);
			layout.add('south', new Ext.ContentPanel('DetailDialog_Footer', 'South'));
			layout.add('center', imgPane);
		layout.endUpdate();

		detailDialog.show();
	},
	// }}}

	// Ext.TabPanelItem selectViewerTab() {{{
	selectViewerTab: function(keyword, holderId, caption, url, stickyTab) {
		var tabId = null;
		var viewerTab = null;
		//
		// show help tab if no keywords
		//
		if(! keyword || keyword.length < 1) {
			//
			// try select target tab
			//
			tabId = holderId;
			viewerTab = Firefly.Stock.viewerTabs.getTab(tabId);
			if(viewerTab) {
				viewerTab.activate();
			}
			else {
				//
				// create new target tab
				//
				viewerTab = Firefly.Stock.viewerTabs.addTab(tabId, caption, '', stickyTab ? false : true);
				var panel = new Ext.ContentPanel(viewerTab.id, { title:	caption });
				viewerTab.activate();
				Ext.get(viewerTab.id).load(url, null, function(elem, r) {
					elem.applyStyles(
						'height:' + Firefly.getViewerContentHeight() + 'px; ' +
						'overflow:auto;');
				});
				Ext.get(viewerTab.id).applyStyles('overflow:auto;');
			}
		}
		else {
			//
			// try select tab
			//
			tabId = String.format('ViewerTabs_Q_{0}', escape(keyword).replace(/%/g, ''));
			viewerTab = Firefly.Stock.viewerTabs.getTab(tabId);
			if(viewerTab) {
				viewerTab.activate();
			}
			else {
				//
				// create new tab
				//
				viewerTab = Firefly.Stock.viewerTabs.addTab(tabId, Firefly.htmlescape(keyword), String.format('<div id="{0}"></div>', holderId), true);
				var panel = new Ext.ContentPanel(holderId, { title: Firefly.htmlescape(keyword) });
				viewerTab.activate();
			}
		}
		return viewerTab;
	},
	// }}}
	// void loadRelatedKeywordsProxy() {{{
	loadRelatedKeywordsProxy: function(keyword) {
		if(keyword.length > 0) {
			Firefly.loadRelatedKeywords(keyword);
			Firefly.loadRelatedImages(null, keyword);
		}
		else
		{
			Firefly.showError('キーワードを入力してください', function(){
				Firefly.Stock.keywordField.focus();
			});
		}
	},
	// }}}

	// void onSidebarTabChanged() {{{
	onSidebarTabChanged: function(tab, item) {
/*
		if(Firefly.currentKeyword)
		{
			Firefly.loadRelatedKeywords(Firefly.currentKeyword);
			Firefly.currentKeyword = null;
		}
*/
	},
	// }}}
	// void loadPopularKeywords() {{{
	loadPopularKeywords: function() {
		Firefly.currentKeyword = null;
		//
		// get active tab and tree
		//
		var tab = Firefly.getSidebarActiveTab();
		var tree = Firefly.getSidebarActiveTree();
		//
		// clear previous results
		//
		Firefly.Stock.clear(tree);
		if(Firefly.isStickyMode()) {
			Firefly.Stock.stickyTree = tree;
		}
		else {
			Firefly.Stock.searchTree = tree;
		}
		//
		// refresh tab
		//
		Firefly.refreshTab(tab, '人気キーワード');
		//
		// attach new tree of results
		//
		tree = Firefly.createSidebarTree(tab, '?m=get_popular_keywords_json', '');
	},
	// }}}
	// void loadRelatedKeywords() {{{
	loadRelatedKeywords: function(keyword) {
		Firefly.currentKeyword = keyword;
		//
		// get active tab and tree
		//
		var tab = Firefly.getSidebarActiveTab();
		var tree = Firefly.getSidebarActiveTree();
		//
		// clear previous results
		//
		Firefly.Stock.clear(tree);
		if(Firefly.isStickyMode()) {
			Firefly.Stock.stickyTree = tree;
		}
		else {
			Firefly.Stock.searchTree = tree;
		}
		//
		// refresh tab
		//
		Firefly.refreshTab(tab, String.format('"{0}"の関連キーワード', keyword));
		//
		// attach new tree of results
		//
		tree = Firefly.createSidebarTree(tab, '?m=get_related_keywords_json', keyword);
	},
	// }}}
	// void loadRelatedImages() {{{
	loadRelatedImages: function(node, directKeywords) {
		//
		// get keyword
		//
		var keyword = node ? node.text : directKeywords;
		Firefly.currentKeyword = keyword;
		if(keyword.length < 1) {
			return;
		}
		//
		// select or create viewer tab
		//
		var holderId = String.format('ImageHolder_{0}', escape(keyword).replace(/%/g, ''));
		var viewerTab = Firefly.selectViewerTab(keyword, holderId);
		//
		// load image information
		//
		var loader = new Ext.JsonView(holderId, Firefly.Stock.thumbTemplate, {
			singleSelect:	true,
			jsonRoot:		'images',
			emptyText:		String.format('<div class="error">"{0}"に関連する画像を取得できませんでした</div>', Firefly.htmlescape(keyword))
		});
		loader.on('load', function(view, data, r) {
			Ext.get(holderId).applyStyles(
				'height:' + Firefly.getViewerContentHeight() + 'px; ' +
				'overflow:auto;');
		});
		loader.load({
			url:		String.format('?m=get_related_images_json&q={0}', encodeURI(keyword)),
			text:		'Now Loading',
			timeout:	30
		});
		loader.on('click', function(view, index, node, e) {
			Firefly.showImageDetailDialog(node);
		});
	},
	// }}}

	// void addSearchPlugin() {{{
	addSearchPlugin: function() {
		var base = String.format('{0}/searchplugins/firefly.', siteRoot);
 		if((typeof(window.sidebar) == "object") && (typeof(window.sidebar.addSearchEngine) == "function")) {
			window.sidebar.addSearchEngine(base + 'src', base + 'png', document.title, '0');
		}
		else {
			alert('Mozilla系ブラウザ以外は自動登録できません。');
		}
	}
	// }}}

};

// loading lancher {{{
Ext.onReady(function() {
	Firefly.initializePageLayout();
	Firefly.initializeSidebar();
	Firefly.initializeViewer();

	switch(OnTheFly.mode) {
		case 'images':
			Firefly.Stock.keywordField.setValue(OnTheFly.keywords);
			Firefly.loadRelatedKeywords(OnTheFly.keywords);
			Firefly.loadRelatedImages(null, OnTheFly.keywords);
			break;

		case 'related':
			Firefly.Stock.keywordField.setValue(OnTheFly.keywords);
			Firefly.loadRelatedKeywords(OnTheFly.keywords);
			Firefly.showHome();
			break;

		case 'popular':
			Firefly.loadPopularKeywords();
			Firefly.showHome();
			break;

		default:
			Firefly.showHome();
			break;
	}

	Ext.get('Toolbar_Keyword').focus();
});
// }}}

