import React, { Component } from 'react';
import { findDOMNode } from 'react-dom';
import Tippy from '@tippy.js/react';
import Sortable from 'sortablejs';

import Window from './Components/Window';
import WindowButtons from './Components/WindowButtons';
import WindowButton from './Components/WindowButton';
import WindowContent from './Components/WindowContent';
import Titlebar from './Components/Titlebar';
import Tabs from './Components/Tabs';
import { TabContainer, Tab, TabIcon, TabTitle, TabStatusIcon, TabCloseButton } from './Components/Tab';
import TabButton from './Components/TabButton';
import TabContent from './Components/TabContent';
import Toolbar from './Components/Toolbar';
import { ToolbarButton, ToolbarButtonBadge } from './Components/ToolbarButton';
import ToolbarDivider from './Components/ToolbarDivider';
import { ToolbarTextBoxWrapper, ToolbarTextBox } from './Components/ToolbarTextBox';
import BookmarkBar from './Components/BookmarkBar';
import ContentWrapper from './Components/ContentWrapper';

import WindowMinimizeIcon from './Resources/windows/minimize.svg';
import WindowMaximizeIcon from './Resources/windows/maximize.svg';
import WindowCloseIcon from './Resources/windows/close.svg';

import DarkBackIcon from './Resources/dark/arrow_back.svg';
import LightBackIcon from './Resources/light/arrow_back.svg';
import DarkForwardIcon from './Resources/dark/arrow_forward.svg';
import LightForwardIcon from './Resources/light/arrow_forward.svg';

import BackInActiveIcon from './Resources/inactive/arrow_back.svg';
import ForwardInActiveIcon from './Resources/inactive/arrow_forward.svg';

import DarkReloadIcon from './Resources/dark/reload.svg';
import LightReloadIcon from './Resources/light/reload.svg';
import DarkHomeIcon from './Resources/dark/home.svg';
import LightHomeIcon from './Resources/light/home.svg';

import DarkInfomationIcon from './Resources/dark/info.svg';
import LightInfomationIcon from './Resources/light/info.svg';

import DarkSecureIcon from './Resources/dark/secure.svg';
import LightSecureIcon from './Resources/light/secure.svg';
import DarkInSecureIcon from './Resources/dark/insecure.svg';
import LightInSecureIcon from './Resources/light/insecure.svg';

import DarkStarIcon from './Resources/dark/star.svg';
import LightStarIcon from './Resources/light/star.svg';
import DarkStarFilledIcon from './Resources/dark/star-filled.svg';
import LightStarFilledIcon from './Resources/light/star-filled.svg';

import DarkFeedbackIcon from './Resources/dark/feedback.svg';
import LightFeedbackIcon from './Resources/light/feedback.svg';
import DarkAccountIcon from './Resources/dark/account.svg';
import LightAccountIcon from './Resources/light/account.svg';

import DarkShieldIcon from './Resources/dark/shield.svg';
import LightShieldIcon from './Resources/light/shield.svg';

import DarkMoreIcon from './Resources/dark/more.svg';
import LightMoreIcon from './Resources/light/more.svg';

import DarkPublicIcon from './Resources/dark/public.svg';
import LightPublicIcon from './Resources/light/public.svg';

import DarkAddIcon from './Resources/dark/add.svg';
import LightAddIcon from './Resources/light/add.svg';
import DarkCloseIcon from './Resources/dark/close.svg';
import LightCloseIcon from './Resources/light/close.svg';
import DarkAudioIcon from './Resources/dark/audio.svg';
import LightAudioIcon from './Resources/light/audio.svg';

import 'tippy.js/themes/light.css';
import 'tippy.js/themes/light-border.css';
import 'tippy.js/themes/google.css';
import 'tippy.js/themes/translucent.css';

import isURL from '../Utils/isURL';

const { remote, ipcRenderer, shell } = window.require('electron');
const { app, systemPreferences, Menu, MenuItem, dialog } = remote;

const pkg = window.require(`${app.getAppPath()}/package.json`);
const protocolStr = 'flast';
const fileProtocolStr = `${protocolStr}-file`;

const platform = window.require('electron-platform');
const { parse, format } = window.require('url');
const path = window.require('path');
const process = window.require('process');

const Config = window.require('electron-store');
const config = new Config();

const lang = window.require(`${app.getAppPath()}/langs/${config.get('language')}.js`);

class BrowserView extends Component {
	constructor(props) {
		super(props);

		this.blockCount = 0;

		this.state = {
			barText: '',
			findText: '',
			previousText: '',
			resultString: '',
			activeMatch: 0,
			certificate: {},
			viewUrl: '',
			isInputed: false,
			isLoading: false,
			canGoBack: false,
			canGoForward: false,
			isBookmarked: false,
			isShowing: true,
		};
	}

	componentDidMount() {
		/*
		let webView = this.refs.webView;
		let props = this.props;

		webView.addEventListener('did-finish-load', (e) => {
			document.title = webView.getTitle();
			this.setText(webView.getURL());
			this.props.updateTab(webView.getTitle(), PublicIcon, webView.getURL(), this.props.index);
			this.setState({ barText: webView.getURL() });
		}, false);

		webView.addEventListener('page-title-updated', (e) => {
			document.title = webView.getTitle();
			this.setText(webView.getURL());
			this.props.updateTab(webView.getTitle(), PublicIcon, webView.getURL(), this.props.index);
			this.setState({ barText: webView.getURL() });
		}, false);

		webView.addEventListener('page-favicon-updated', (e) => {
			if (e.favicons.length > 0) {
				this.props.updateTab(webView.getTitle(), e.favicons[0], webView.getURL(), this.props.index);
			} else {
				this.props.updateTab(webView.getTitle(), PublicIcon, webView.getURL(), this.props.index);
			}
		});

		webView.addEventListener('load-commit', (e) => {
			if (e.isMainFrame) {
				document.title = webView.getTitle();
				this.setText(webView.getURL());
				this.props.updateTab(webView.getTitle(), PublicIcon, webView.getURL(), this.props.index);
				this.setState({ barText: webView.getURL() });
			}
		});

		webView.addEventListener('found-in-page', (e, result) => {
			if (result.activeMatchOrdinal) {
				this.setState({
					activeMatch: result.activeMatchOrdinal,
					resultString: `${this.state.activeMatch}/${result.matches}`
				});
			}

			if (result.finalUpdate) {
				this.setState({ resultString: `${this.state.activeMatch}/${result.matches}` });
			}
		});

		webView.addEventListener('new-window', (e, url) => {
			this.props.addTab('新しいタブ', '', e.url);
		});
		*/

		ipcRenderer.on(`browserview-start-loading-${this.props.windowId}`, (e, args) => {
			if (args.id === this.props.index) {
				this.setState({ isLoading: true });
				this.blockCount = 0;
			}
		});

		ipcRenderer.on(`browserview-stop-loading-${this.props.windowId}`, (e, args) => {
			if (args.id === this.props.index) {
				this.setState({ isLoading: false });
			}
		});

		ipcRenderer.on(`browserview-load-${this.props.windowId}`, (e, args) => {
			if (args.id === this.props.index) {
				this.props.updateTab();
				this.setState({ viewUrl: args.url, isBookmarked: args.isBookmarked });
				if (!this.state.isInputed)
					this.setText(args.url);
			}
		});

		ipcRenderer.on(`browserview-certificate-${this.props.windowId}`, (e, args) => {
			if (args.id === this.props.index) {
				this.setState({ certificate: args.certificate });
			}
		});

		ipcRenderer.on(`blocked-ad-${this.props.windowId}`, (e, args) => {
			if (args.id === this.props.index) {
				this.blockCount++
			}
		});

		ipcRenderer.on(`update-navigation-state-${this.props.windowId}`, (e, args) => {
			if (args.id === this.props.index) {
				this.setState({ canGoBack: args.canGoBack, canGoForward: args.canGoForward });
			}
		});

		ipcRenderer.on(`browserview-permission-${this.props.windowId}`, (e, args) => {
			if (args.id === this.props.index) {
				const toolTip = findDOMNode(this.infomationTooltip)._tippy;
				toolTip.setContent(args.content);
				toolTip.show();
				setTimeout(() => {
					toolTip.hide();
				}, 1250);
			}
		});

		ipcRenderer.on(`notification-${this.props.windowId}`, (e, args) => {
			if (args.id === this.props.index) {
				const toolTip = findDOMNode(this.infomationTooltip)._tippy;
				toolTip.setContent(args.content);
				toolTip.show();
				setTimeout(() => {
					toolTip.hide();
				}, 1250);
			}
		});
	}

	handleKeyDown = (e) => {
		if (e.key !== 'Enter') return;

		if (this.state.barText.length > 0 || this.state.barText !== '') {
			this.setState({ isInputed: false });
			if (isURL(this.state.barText) && !this.state.barText.includes('://')) {
				ipcRenderer.send(`browserview-loadURL-${this.props.windowId}`, { id: this.props.index, url: `http://${this.state.barText}` });
			} else if (!this.state.barText.includes('://')) {
				ipcRenderer.send(`browserview-loadURL-${this.props.windowId}`, { id: this.props.index, url: this.getSearchEngine().url.replace('%s', this.state.barText) });
			} else {
				const pattern = /^(file:\/\/\S.*)\S*$/;

				if (pattern.test(this.state.barText)) {
					ipcRenderer.send(`browserview-loadFile-${this.props.windowId}`, { id: this.props.index, url: this.state.barText.replace('file:///', '') });
				} else {
					ipcRenderer.send(`browserview-loadURL-${this.props.windowId}`, { id: this.props.index, url: this.state.barText });
				}
			}
		} else {
			this.setState({ isInputed: false });
			this.setText(this.state.viewUrl);
		}
	}

	handleContextMenu = (e) => {
		const menu = Menu.buildFromTemplate([
			{
				label: lang.window.view.contextMenu.editable.undo,
				accelerator: 'CmdOrCtrl+Z',
				role: 'undo'
			},
			{
				label: lang.window.view.contextMenu.editable.redo,
				accelerator: 'CmdOrCtrl+Y',
				role: 'redo'
			},
			{ type: 'separator' },
			{
				label: lang.window.view.contextMenu.editable.cut,
				accelerator: 'CmdOrCtrl+X',
				role: 'cut'
			},
			{
				label: lang.window.view.contextMenu.editable.copy,
				accelerator: 'CmdOrCtrl+C',
				role: 'copy'
			},
			{
				label: lang.window.view.contextMenu.editable.paste,
				accelerator: 'CmdOrCtrl+V',
				role: 'paste'
			},
			{ type: 'separator' },
			{
				label: lang.window.view.contextMenu.editable.selectAll,
				accelerator: 'CmdOrCtrl+A',
				role: 'selectAll'
			}
		]);
		menu.popup();
	}

	getSearchEngine = () => {
		for (var i = 0; i < config.get('searchEngine.searchEngines').length; i++) {
			if (config.get('searchEngine.searchEngines')[i].name === config.get('searchEngine.defaultEngine')) {
				return config.get('searchEngine.searchEngines')[i];
			}
		}
	}

	setText = (text) => {
		this.setState({ barText: text });
	}

	goBack = () => {
		ipcRenderer.send(`browserview-goBack-${this.props.windowId}`, { id: this.props.index });
	}

	goForward = () => {
		ipcRenderer.send(`browserview-goForward-${this.props.windowId}`, { id: this.props.index });
	}

	reload = () => {
		if (!this.state.isLoading) {
			ipcRenderer.send(`browserview-reload-${this.props.windowId}`, { id: this.props.index });
		} else {
			ipcRenderer.send(`browserview-stop-${this.props.windowId}`, { id: this.props.index });
		}
	}

	goHome = () => {
		ipcRenderer.send(`browserview-goHome-${this.props.windowId}`, { id: this.props.index });
	}

	certificate = () => {
		const toolTip = findDOMNode(this.infomationTooltip)._tippy;
		if (this.state.certificate.type === 'Internal')
			toolTip.setContent(lang.window.toolBar.addressBar.info.clicked.internal);
		if (this.state.certificate.type === 'Secure')
			toolTip.setContent(`<span style="color: green;">${this.state.certificate !== undefined ? `${this.state.certificate.title} [${this.state.certificate.country}]` : lang.window.toolBar.addressBar.info.clicked.secure}</span>`);
		if (this.state.certificate.type === 'InSecure')
			toolTip.setContent(`<span style="color: red;">${lang.window.toolBar.addressBar.info.clicked.insecure}</span>`);
		if (toolTip.popperChildren.content !== undefined && toolTip.popperChildren.content !== null) {
			toolTip.show();
			setTimeout(() => {
				toolTip.hide();
			}, 1000 * 3);
		}
	}

	bookMark = () => {
		const toolTip = findDOMNode(this.markTooltip)._tippy;
		toolTip.show();
		setTimeout(() => {
			toolTip.hide();
		}, 1250);
		if (this.state.isBookmarked)
			ipcRenderer.send(`data-bookmark-remove-${this.props.windowId}`, { id: this.props.index, isPrivate: this.props.windowId.startsWith('private') });
		else
			ipcRenderer.send(`data-bookmark-add-${this.props.windowId}`, { id: this.props.index, isPrivate: this.props.windowId.startsWith('private') });
	}

	userMenu = async () => {
		const menu = Menu.buildFromTemplate([
			{
				label: (!this.props.windowId.startsWith('private') ? `${process.env.USERNAME} でログイン中` : 'プライベートモード'),
				enabled: false,
			},
			{ type: 'separator' },
			{
				label: lang.window.toolBar.menu.menus.close,
				click: () => { remote.getCurrentWindow().close(); }
			}
		]);
		menu.popup({
			x: remote.getCurrentWindow().getSize()[0] - 57,
			y: 65
		});
	}

	moreMenu = () => {
		const menu = Menu.buildFromTemplate([
			{
				label: lang.window.toolBar.menu.menus.newTab,
				accelerator: 'CmdOrCtrl+T',
				click: () => { this.props.addTab(config.get('homePage.defaultPage')); }
			},
			{
				label: lang.window.toolBar.menu.menus.newWindow,
				accelerator: 'CmdOrCtrl+N',
				click: () => { ipcRenderer.send(`window-add`, { isPrivate: false }); }
			},
			{
				label: lang.window.toolBar.menu.menus.openPrivateWindow,
				accelerator: 'CmdOrCtrl+Shift+N',
				click: () => { ipcRenderer.send(`window-add`, { isPrivate: true }); }
			},
			{ type: 'separator' },
			{
				label: lang.window.toolBar.menu.menus.history,
				icon: `${app.getAppPath()}/static/history.png`,
				click: () => { this.props.addTab(`${protocolStr}://history/`); }
			},
			{
				label: lang.window.toolBar.menu.menus.downloads,
				icon: `${app.getAppPath()}/static/download.png`,
				click: () => { this.props.addTab(`${protocolStr}://downloads/`); }
			},
			{
				label: lang.window.toolBar.menu.menus.bookmarks,
				icon: `${app.getAppPath()}/static/bookmarks.png`,
				click: () => { this.props.addTab(`${protocolStr}://bookmarks/`); }
			},
			{
				label: lang.window.toolBar.menu.menus.app.name,
				type: 'submenu',
				submenu: [
					{
						label: lang.window.toolBar.menu.menus.app.list,
						icon: `${app.getAppPath()}/static/apps.png`,
						click: () => { this.props.addTab(`${protocolStr}://apps/`); }
					},
					{ type: 'separator' },
					{
						label: lang.window.toolBar.menu.menus.app.store,
						icon: `${app.getAppPath()}/static/shop.png`,
						enabled: false,
						click: () => { this.props.addTab(`http://store.aoichaan0513.xyz/`); }
					},
				]
			},
			{ type: 'separator' },
			{
				label: lang.window.toolBar.menu.menus.print,
				icon: `${app.getAppPath()}/static/print.png`,
				enabled: false,
				click: () => { this.props.addTab(`${protocolStr}://history/`); }
			},
			{
				label: lang.window.toolBar.menu.menus.find,
				icon: `${app.getAppPath()}/static/find.png`,
				enabled: false,
				click: () => { this.props.addTab(`${protocolStr}://history/`); }
			},
			{ type: 'separator' },
			{
				label: lang.window.toolBar.menu.menus.settings,
				icon: `${app.getAppPath()}/static/settings.png`,
				click: () => { this.props.addTab(`${protocolStr}://settings/`); }
			},
			{
				label: lang.window.toolBar.menu.menus.help,
				icon: `${app.getAppPath()}/static/help_outline.png`,
				click: () => { this.props.addTab(`${protocolStr}://help/`); }
			},
			{ type: 'separator' },
			{
				label: lang.window.toolBar.menu.menus.close,
				click: () => { this.props.closeWindow(); }
			}
		]);
		menu.popup({
			x: remote.getCurrentWindow().getSize()[0] - 24,
			y: 65
		});
	}

	isDarkModeOrPrivateMode = () => {
		return config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private');
	}

	isDarkModeOrPrivateMode = (lightMode, darkMode) => {
		return !(config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private')) ? lightMode : darkMode;
	}

	render() {
		return (
			<ContentWrapper>
				<Toolbar isDarkModeOrPrivateMode={config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private')} isBookmarkBar={config.get('design.isBookmarkBar')}>
					<ToolbarButton isDarkModeOrPrivateMode={config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private')} src={this.state.canGoBack ? this.isDarkModeOrPrivateMode.bind(this, LightBackIcon, DarkBackIcon) : BackInActiveIcon} size={24}
						isShowing={true} isRight={false} isMarginLeft={true} isEnabled={this.state.canGoBack} title={lang.window.toolBar.back} onClick={() => { this.goBack(); }} />
					<ToolbarButton isDarkModeOrPrivateMode={config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private')} src={this.state.canGoForward ? this.isDarkModeOrPrivateMode.bind(this, LightForwardIcon, DarkForwardIcon) : ForwardInActiveIcon} size={24}
						isShowing={true} isRight={false} isMarginLeft={false} isEnabled={this.state.canGoForward} title={lang.window.toolBar.forward} onClick={() => { this.goForward(); }} />
					<ToolbarButton isDarkModeOrPrivateMode={config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private')} src={!this.state.isLoading ? this.isDarkModeOrPrivateMode.bind(this, LightReloadIcon, DarkReloadIcon) : this.isDarkModeOrPrivateMode.bind(this, LightCloseIcon, DarkCloseIcon)} size={24}
						isShowing={true} isRight={false} isMarginLeft={false} isEnabled={true} title={!this.state.isLoading ? lang.window.toolBar.reload.reload : lang.window.toolBar.reload.stop} onClick={() => { this.reload(); }} />
					<ToolbarButton isDarkModeOrPrivateMode={config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private')} src={this.isDarkModeOrPrivateMode.bind(this, LightHomeIcon, DarkHomeIcon)} size={24}
						isShowing={config.get('design.isHomeButton')} isRight={false} isMarginLeft={false} isEnabled={true} title={lang.window.toolBar.home} onClick={() => { this.goHome(); }} />
					<ToolbarTextBoxWrapper isDarkModeOrPrivateMode={config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private')} buttonCount={config.get('design.isHomeButton') ? 6 : 5}>
						<Tippy ref={ref => { this.infomationTooltip = ref; }} theme={config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private') ? 'dark' : 'light'} placement="right" arrow={true} trigger="manual">
							<ToolbarButton src={this.state.certificate !== undefined && this.state.certificate !== null && (this.state.certificate.type === 'Internal' || this.state.certificate.type === 'Secure') ? this.isDarkModeOrPrivateMode.bind(this, LightSecureIcon, DarkSecureIcon) : this.isDarkModeOrPrivateMode.bind(this, LightInSecureIcon, DarkInSecureIcon)} size={12}
								isShowing={true} isRight={false} isMarginLeft={true} isEnabled={true} title={lang.window.toolBar.addressBar.info.name} onClick={() => { this.certificate(); }} />
						</Tippy>
						<ToolbarTextBox value={this.state.barText} onChange={(e) => { this.setState({ barText: e.target.value }); }} onKeyDown={this.handleKeyDown} onFocus={(e) => { e.target.select(); this.setState({ isInputed: true }); }} onContextMenu={this.handleContextMenu} />
						<Tippy ref={ref => { this.markTooltip = ref; }} content={!this.state.isBookmarked ? (this.props.windowId.startsWith('private') ? lang.window.toolBar.addressBar.bookmark.clicked.removePrivate : lang.window.toolBar.addressBar.bookmark.clicked.remove) : (this.props.windowId.startsWith('private') ? lang.window.toolBar.addressBar.bookmark.clicked.addPrivate : lang.window.toolBar.addressBar.bookmark.clicked.add)} theme={config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private') ? 'dark' : 'light'} placement="left" arrow={true} trigger="manual">
							<ToolbarButton isDarkModeOrPrivateMode={config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private')} src={this.state.isBookmarked ? this.isDarkModeOrPrivateMode.bind(this, LightStarFilledIcon, DarkStarFilledIcon) : this.isDarkModeOrPrivateMode.bind(this, LightStarIcon, DarkStarIcon)} size={12}
								isShowing={true} isRight={true} isMarginLeft={true} isEnabled={true} title={this.state.isBookmarked ? lang.window.toolBar.addressBar.bookmark.remove : lang.window.toolBar.addressBar.bookmark.add} onClick={() => { this.bookMark(); }} />
						</Tippy>
					</ToolbarTextBoxWrapper>
					{config.get('isAdBlock') &&
						<ToolbarButton isDarkModeOrPrivateMode={config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private')} src={this.isDarkModeOrPrivateMode.bind(this, LightShieldIcon, DarkShieldIcon)} size={24}
							isShowing={true} isRight={true} isMarginLeft={true} isEnabled={true} title={String(lang.window.toolBar.extensions.adBlock).replace(/{replace}/, this.blockCount)}>
							{this.blockCount > 0 && <ToolbarButtonBadge>{this.blockCount}</ToolbarButtonBadge>}
						</ToolbarButton>
					}
					<ToolbarButton isDarkModeOrPrivateMode={config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private')} src={this.isDarkModeOrPrivateMode.bind(this, LightFeedbackIcon, DarkFeedbackIcon)} size={24}
						isShowing={true} isRight={true} isMarginLeft={true} isEnabled={true} title={lang.window.toolBar.extensions.feedback} onClick={() => { this.props.addTab('https://join.slack.com/t/serene-develop/shared_invite/enQtNjQwOTQwOTExMTM5LTg1OTNiNGFkNzU5NDEwYTJmNTY5MDk2MzI2YTU4NmYxZWRlMjMwMGY3MmUzMDM5N2QwZjUyZjNiNTczMjkyNWE'); }} />
					<ToolbarDivider isDarkModeOrPrivateMode={config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private')} />
					<ToolbarButton isDarkModeOrPrivateMode={config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private')} src={this.props.windowId.startsWith('private') ? this.isDarkModeOrPrivateMode.bind(this, LightShieldIcon, DarkShieldIcon) : this.isDarkModeOrPrivateMode.bind(this, LightAccountIcon, DarkAccountIcon)} size={24}
						isShowing={true} isRight={true} isMarginLeft={true} isEnabled={true} title={this.props.windowId.startsWith('private') ? 'プライベートモード' : process.env.USERNAME} onClick={() => { this.userMenu(); }} />
					<ToolbarButton isDarkModeOrPrivateMode={config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private')} src={this.isDarkModeOrPrivateMode.bind(this, LightMoreIcon, DarkMoreIcon)} size={24}
						isShowing={true} isRight={true} isMarginLeft={false} isEnabled={true} title={lang.window.toolBar.menu.name} onClick={() => { this.moreMenu(); }} />
				</Toolbar>
				<BookmarkBar isDarkModeOrPrivateMode={config.get('design.isDarkTheme') || String(this.props.windowId).startsWith('private')} isBookmarkBar={config.get('design.isBookmarkBar')} />
			</ContentWrapper>
		);
	}
}

class BrowserWindow extends Component {
	constructor(props) {
		super(props);

		this.state = {
			tabs: [],
			current: 0
		};

		ipcRenderer.on(`window-focus-${this.props.match.params.windowId}`, (e, args) => {
			this.forceUpdate();
		});
		ipcRenderer.on(`window-blur-${this.props.match.params.windowId}`, (e, args) => {
			this.forceUpdate();
		});

		ipcRenderer.on('window-change-settings', (e, args) => {
			this.forceUpdate();
		});

		ipcRenderer.on(`tab-add-${this.props.match.params.windowId}`, (e, args) => {
			this.addTab(args.url);
		});

		ipcRenderer.on(`browserview-get-${this.props.match.params.windowId}`, (e, args) => {
			this.setState({ tabs: args.views });
		});

		ipcRenderer.on(`browserview-set-${this.props.match.params.windowId}`, (e, args) => {
			this.setState({ current: args.id });
		});
	}

	componentDidMount = () => {
		let sortable = Sortable.create(findDOMNode(this.tabContainer), {
			group: this.props.match.params.windowId,
			animation: 100
		});

		this.addTab();
	}

	handleContextMenu = (i) => {
		const menu = Menu.buildFromTemplate([
			{
				label: '新しいタブ',
				accelerator: 'CmdOrCtrl+T',
				click: () => { this.addTab(); }
			},
			{
				label: 'タブを閉じる',
				accelerator: 'CmdOrCtrl+W',
				click: () => { this.removeTab(i); }
			},
			{ type: 'separator' },
			{
				type: 'checkbox',
				label: 'タブを固定',
				checked: this.state.tabs[i].fixed,
				click: () => {
					var newTabs = this.state.tabs.concat();
					newTabs[i].fixed = !this.state.tabs[i].fixed;
					this.setState({ tabs: newTabs });
				}
			}
		]);
		menu.popup(remote.getCurrentWindow());
	}

	getTabs = () => {
		ipcRenderer.send(`browserview-get-${this.props.match.params.windowId}`, {});
	}

	addTab = (url = (config.get('homePage.isDefaultHomePage') ? `${protocolStr}://home/` : config.get('homePage.defaultPage'))) => {
		ipcRenderer.send(`browserview-add-${this.props.match.params.windowId}`, { url, isActive: true });
		ipcRenderer.send(`browserview-get-${this.props.match.params.windowId}`, {});
		this.setState({ current: this.state.tabs.length });
	}

	removeTab = (i) => {
		ipcRenderer.send(`browserview-remove-${this.props.match.params.windowId}`, { id: i });
		ipcRenderer.send(`browserview-get-${this.props.match.params.windowId}`, {});

		this.forceUpdate();
		if ((this.state.tabs.length - 1) < 1) {
			remote.getCurrentWindow().close();
		}
	}

	updateTab = () => {
		ipcRenderer.send(`browserview-get-${this.props.match.params.windowId}`, {});
	}

	getForegroundColor = (hexColor) => {
		var r = parseInt(hexColor.substr(1, 2), 16);
		var g = parseInt(hexColor.substr(3, 2), 16);
		var b = parseInt(hexColor.substr(5, 2), 16);

		return ((((r * 299) + (g * 587) + (b * 114)) / 1000) < 128) ? '#ffffff' : '#000000';
	}

	isDarkModeOrPrivateMode = () => {
		return config.get('design.isDarkTheme') || String(this.props.match.params.windowId).startsWith('private');
	}

	isDarkModeOrPrivateMode = (lightMode, darkMode) => {
		return !(config.get('design.isDarkTheme') || String(this.props.match.params.windowId).startsWith('private')) ? lightMode : darkMode;
	}

	closeWindow = () => {
		if (this.state.tabs.length > 1) {
			if (config.get('window.isCloseConfirm')) {
				dialog.showMessageBox(remote.getCurrentWindow(), {
					type: 'info',
					title: 'アプリ終了確認',
					message: `${this.state.tabs.length}個のタブを閉じようとしています。`,
					detail: `${this.state.tabs.length}個のタブを閉じてアプリを終了しようとしています。\n複数のタブを閉じてアプリを終了してもよろしいでしょうか？`,
					checkboxLabel: '今後は確認しない',
					checkboxChecked: false,
					noLink: true,
					buttons: ['はい / Yes', 'いいえ / No'],
					defaultId: 0,
					cancelId: 1
				}, (res, checked) => {
					if (checked)
						config.set('window.isCloseConfirm', false);
					if (res === 0)
						remote.getCurrentWindow().close();
				});
			} else {
				remote.getCurrentWindow().close();
			}
		} else {
			remote.getCurrentWindow().close();
		}
	}

	render() {
		return (
			<Window isCustomTitlebar={config.get('design.isCustomTitlebar')}>
				<Titlebar isActive={remote.getCurrentWindow().isFocused()} color={!String(this.props.match.params.windowId).startsWith('private') ? (platform.isWin32 || platform.isDarwin ? `#${systemPreferences.getAccentColor()}` : '#353535') : '#353535'}>
					<WindowButtons isCustomTitlebar={config.get('design.isCustomTitlebar')} isWindowsOrLinux={platform.isWin32 || !(platform.isWin32 && platform.isDarwin)}>
						<WindowButton isClose={true} isMinimize={false} isWindowsOrLinux={platform.isWin32 || !(platform.isWin32 && platform.isDarwin)} title={lang.window.titleBar.buttons.close} onClick={() => { this.closeWindow(); }} />
						<WindowButton isClose={false} isMinimize={true} isWindowsOrLinux={platform.isWin32 || !(platform.isWin32 && platform.isDarwin)} title={lang.window.titleBar.buttons.minimize} onClick={() => { remote.getCurrentWindow().minimize(); }} />
						<WindowButton isClose={false} isMinimize={false} isWindowsOrLinux={platform.isWin32 || !(platform.isWin32 && platform.isDarwin)} title={remote.getCurrentWindow().isMaximized() ? lang.window.titleBar.buttons.maximize.restore : lang.window.titleBar.buttons.maximize.maximize} onClick={() => { remote.getCurrentWindow().isMaximized() ? remote.getCurrentWindow().unmaximize() : remote.getCurrentWindow().maximize(); this.forceUpdate(); }} />
					</WindowButtons>
					<Tabs isCustomTitlebar={config.get('design.isCustomTitlebar')} isWindowsOrLinux={platform.isWin32 || !(platform.isWin32 && platform.isDarwin)}>
						<TabContainer ref={ref => { this.tabContainer = ref; }}>
							{this.state.tabs.map((tab, i) => {
								return (
									<Tab isDarkModeOrPrivateMode={config.get('design.isDarkTheme') || String(this.props.match.params.windowId).startsWith('private')} isActive={tab.id === this.state.current} isFixed={tab.fixed} accentColor={tab.color} onClick={() => { ipcRenderer.send(`browserview-select-${this.props.match.params.windowId}`, { id: tab.id }); this.forceUpdate(); }} onContextMenu={this.handleContextMenu.bind(this, tab.id)}>
										<TabIcon src={tab.icon !== undefined ? tab.icon : (config.get('design.isDarkTheme') || String(this.props.match.params.windowId).startsWith('private') ? DarkPublicIcon : LightPublicIcon)} width={18} height={18} />
										<TabTitle color={this.getForegroundColor(!config.get('design.isDarkTheme') || !String(this.props.match.params.windowId).startsWith('private') ? (platform.isWin32 || platform.isDarwin ? `#${systemPreferences.getAccentColor()}` : '#353535') : '#353535')} isAudioPlaying={tab.isAudioPlaying} isFixed={tab.fixed} title={tab.title}>{tab.title}</TabTitle>
										<TabCloseButton isActive={tab.id === this.state.current} isFixed={tab.fixed} isRight={true} src={this.isDarkModeOrPrivateMode.bind(this, LightCloseIcon, DarkCloseIcon)} size={14} title={lang.window.titleBar.tab.close} onClick={() => { this.removeTab(tab.id); this.forceUpdate(); }} />
									</Tab>
								);
							})}
						</TabContainer>
						<TabButton isRight={true} src={this.isDarkModeOrPrivateMode.bind(this, LightAddIcon, DarkAddIcon)} size={24} title={lang.window.titleBar.tab.new} onClick={() => { this.addTab(); }} />
					</Tabs>
					<WindowButtons isCustomTitlebar={config.get('design.isCustomTitlebar')} isWindowsOrLinux={platform.isWin32 || !(platform.isWin32 && platform.isDarwin)}>
						<WindowButton isClose={false} isWindowsOrLinux={platform.isWin32 || !(platform.isWin32 && platform.isDarwin)} title={lang.window.titleBar.buttons.minimize} onClick={() => { remote.getCurrentWindow().minimize(); }}>
							<svg name="TitleBarMinimize" width="12" height="12" viewBox="0 0 12 12" fill={String(this.props.match.params.windowId).startsWith('private') ? '#ffffff' : '#000000'}>
								<rect width="10" height="1" x="1" y="6" />
							</svg>
						</WindowButton>
						<WindowButton isClose={false} isWindowsOrLinux={platform.isWin32 || !(platform.isWin32 && platform.isDarwin)} title={remote.getCurrentWindow().isMaximized() ? lang.window.titleBar.buttons.maximize.restore : lang.window.titleBar.buttons.maximize.maximize} onClick={() => { remote.getCurrentWindow().isMaximized() ? remote.getCurrentWindow().unmaximize() : remote.getCurrentWindow().maximize(); this.forceUpdate(); }}>
							<svg name="TitleBarMaximize" width="12" height="12" viewBox="0 0 12 12" stroke={String(this.props.match.params.windowId).startsWith('private') ? '#ffffff' : '#000000'}>
								<rect fill="none" width="9" height="9" x="1.5" y="1.5" />
							</svg>
						</WindowButton>
						<WindowButton isClose={true} isWindowsOrLinux={platform.isWin32 || !(platform.isWin32 && platform.isDarwin)} title={lang.window.titleBar.buttons.close} onClick={() => { this.closeWindow(); }}>
							<svg name="TitleBarClose" width="12" height="12" viewBox="0 0 12 12" fill={String(this.props.match.params.windowId).startsWith('private') ? '#ffffff' : '#000000'}>
								<polygon fill-rule="evenodd" points="11 1.576 6.583 6 11 10.424 10.424 11 6 6.583 1.576 11 1 10.424 5.417 6 1 1.576 1.576 1 6 5.417 10.424 1" />
							</svg>
						</WindowButton>
					</WindowButtons>
				</Titlebar>
				<WindowContent>
					{this.state.tabs.map((tab, i) => {
						return (
							<TabContent isActive={tab.id === this.state.current}>
								<BrowserView key={i} windowId={this.props.match.params.windowId} index={tab.id} url={tab.url}
									closeWindow={() => { this.closeWindow(); }}
									addTab={(url) => { this.addTab(url); }}
									updateTab={() => { this.updateTab(); }} />
							</TabContent>
						);
					})}
				</WindowContent>
			</Window>
		);
	}
}

export default BrowserWindow;