/****************************************************************
 *  RetroShare is distributed under the following license:
 *
 *  Copyright (C) 2015, RetroShare Team
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, 
 *  Boston, MA  02110-1301, USA.
 ****************************************************************/

#include <QMenu>

#include "RsBanListToolButton.h"
#include "util/RsNetUtil.h"

#include <retroshare/rsbanlist.h>

/* Use MenuButtonPopup, because the arrow of InstantPopup is too small */
#define USE_MENUBUTTONPOPUP

RsBanListToolButton::RsBanListToolButton(QWidget *parent) :
    QToolButton(parent)
{
	mList = LIST_WHITELIST;
	mMode = MODE_ADD;

	setToolButtonStyle(Qt::ToolButtonTextBesideIcon);

#ifdef USE_MENUBUTTONPOPUP
	connect(this, SIGNAL(clicked()), this, SLOT(showMenu()));
#endif

	updateUi();
}

void RsBanListToolButton::setMode(List list, Mode mode)
{
	mList = list;
	mMode = mode;
	updateUi();
}

bool RsBanListToolButton::setIpAddress(const QString &ipAddress)
{
	mIpAddress.clear();

	if (ipAddress.isEmpty()) {
		updateUi();
		return false;
	}

	struct sockaddr_storage addr;
	int bytes ;

	if (!RsNetUtil::parseAddrFromQString(ipAddress, addr, bytes) || bytes != 0) {
		updateUi();
		return false;
	}

	mIpAddress = ipAddress;
	updateUi();

	return true;
}

void RsBanListToolButton::updateUi()
{
#ifdef USE_MENUBUTTONPOPUP
	setPopupMode(QToolButton::MenuButtonPopup);
#else
	setPopupMode(QToolButton::InstantPopup);
#endif

	switch (mList) {
	case LIST_WHITELIST:
		switch (mMode) {
		case MODE_ADD:
			setText(tr("Add IP to whitelist"));
			break;
		case MODE_REMOVE:
			setText(tr("Remove IP from whitelist"));
			break;
		}
		break;
	case LIST_BLACKLIST:
		switch (mMode) {
		case MODE_ADD:
			setText(tr("Add IP to blacklist"));
			break;
		case MODE_REMOVE:
			setText(tr("Remove IP from blacklist"));
			break;
		}
		break;
	}

	if (!mIpAddress.isEmpty()) {
		sockaddr_storage addr ;
		int masked_bytes ;

		if (RsNetUtil::parseAddrFromQString(mIpAddress, addr, masked_bytes)) {
			QMenu *m = new QMenu;

			m->addAction(QString("%1 %2").arg(tr("Only IP"), RsNetUtil::printAddrRange(addr, 0)), this, SLOT(applyIp()))->setData(0);
			m->addAction(QString("%1 %2").arg(tr("Entire range"), RsNetUtil::printAddrRange(addr, 1)), this, SLOT(applyIp()))->setData(1);
			m->addAction(QString("%1 %2").arg(tr("Entire range"), RsNetUtil::printAddrRange(addr, 2)), this, SLOT(applyIp()))->setData(2);

			setMenu(m);
		} else {
			setMenu(NULL);
		}

		setToolTip(mIpAddress);
	} else {
		setMenu(NULL);
		setToolTip("");
	}
}

void RsBanListToolButton::applyIp()
{
	QAction *action = dynamic_cast<QAction*>(sender());
	if (!action) {
		return;
	}

	sockaddr_storage addr;
	int masked_bytes;

	if (!RsNetUtil::parseAddrFromQString(mIpAddress, addr, masked_bytes)) {
		return;
	}

	uint32_t list_type;
	switch (mList) {
	case LIST_WHITELIST:
		list_type = RSBANLIST_TYPE_WHITELIST;
		break;
	case LIST_BLACKLIST:
		list_type = RSBANLIST_TYPE_BLACKLIST;
		break;
	}

	masked_bytes = action->data().toUInt();
	bool changed = false;

	switch (mMode) {
	case MODE_ADD:
		changed = rsBanList->addIpRange(addr, masked_bytes, list_type, "");
		break;
	case MODE_REMOVE:
		changed = rsBanList->removeIpRange(addr, masked_bytes, list_type);
		break;
	}

	if (changed) {
		emit banListChanged(RsNetUtil::printAddrRange(addr, masked_bytes));
	}
}
