/* $Id$ */
/* Copyright (c) 2013-2020 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Phone */
/* Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY ITS AUTHORS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */



#include <string.h>
#include <System.h>
#include <Desktop.h>
#include "Phone.h"


/* Password */
/* private */
/* types */
typedef struct _PhonePlugin
{
	PhonePluginHelper * helper;

	/* password */
	GtkWidget * window;
	GtkWidget * entry;
	GtkWidget * oldpassword;
	GtkWidget * newpassword;
	GtkWidget * newpassword2;
} PasswordPhonePlugin;


/* prototypes */
/* plug-in */
static PasswordPhonePlugin * _password_init(PhonePluginHelper * helper);
static void _password_destroy(PasswordPhonePlugin * password);
static int _password_event(PasswordPhonePlugin * password, PhoneEvent * event);
static void _password_settings(PasswordPhonePlugin * password);


/* public */
/* variables */
PhonePluginDefinition plugin =
{
	"Password",
	"stock_lock",
	NULL,
	_password_init,
	_password_destroy,
	_password_event,
	_password_settings
};


/* private */
/* functions */
/* password_init */
static PasswordPhonePlugin * _password_init(PhonePluginHelper * helper)
{
	PasswordPhonePlugin * password;

	if((password = object_new(sizeof(*password))) == NULL)
		return NULL;
	password->helper = helper;
	password->window = NULL;
	return password;
}


/* password_destroy */
static void _password_destroy(PasswordPhonePlugin * password)
{
	object_delete(password);
}


/* password_event */
static int _password_event(PasswordPhonePlugin * password, PhoneEvent * event)
{
	(void) password;

	switch(event->type)
	{
		default:
			break;
	}
	return 0;
}


/* password_settings */
static void _on_settings_cancel(gpointer data);
static gboolean _on_settings_closex(gpointer data);
static void _on_settings_ok(gpointer data);
static void _on_settings_ok_error(PasswordPhonePlugin * password,
		char const * error);

static void _password_settings(PasswordPhonePlugin * password)
{
	GtkSizeGroup * group;
	GtkWidget * vbox;
	GtkWidget * hbox;
	GtkWidget * widget;

	if(password->window != NULL)
	{
		gtk_window_present(GTK_WINDOW(password->window));
		return;
	}
	group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
	password->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_container_set_border_width(GTK_CONTAINER(password->window), 4);
	gtk_window_set_default_size(GTK_WINDOW(password->window), 200, 300);
#if GTK_CHECK_VERSION(2, 6, 0)
	/* XXX find something more appropriate */
	gtk_window_set_icon_name(GTK_WINDOW(password->window), "stock_lock");
#endif
	gtk_window_set_title(GTK_WINDOW(password->window), "Password");
	g_signal_connect_swapped(password->window, "delete-event", G_CALLBACK(
				_on_settings_closex), password);
	vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 4);
	/* entry */
	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
	widget = gtk_label_new("Name: ");
#if GTK_CHECK_VERSION(3, 0, 0)
	g_object_set(widget, "halign", GTK_ALIGN_START, NULL);
#else
	gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5);
#endif
	gtk_size_group_add_widget(group, widget);
	gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0);
#if GTK_CHECK_VERSION(2, 24, 0)
	password->entry = gtk_combo_box_text_new_with_entry();
	gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(password->entry),
			"SIM PIN");
#else
	password->entry = gtk_combo_box_entry_new_text();
	gtk_combo_box_append_text(GTK_COMBO_BOX(password->entry), "SIM PIN");
#endif
	gtk_box_pack_start(GTK_BOX(hbox), password->entry, TRUE, TRUE, 0);
	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
	/* old password */
	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
	widget = gtk_label_new("Old password: ");
#if GTK_CHECK_VERSION(3, 0, 0)
	g_object_set(widget, "halign", GTK_ALIGN_START, NULL);
#else
	gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5);
#endif
	gtk_size_group_add_widget(group, widget);
	gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0);
	password->oldpassword = gtk_entry_new();
	gtk_entry_set_visibility(GTK_ENTRY(password->oldpassword), FALSE);
	gtk_box_pack_start(GTK_BOX(hbox), password->oldpassword, TRUE, TRUE, 0);
	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
	/* new password */
	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
	widget = gtk_label_new("New password: ");
#if GTK_CHECK_VERSION(3, 0, 0)
	g_object_set(widget, "halign", GTK_ALIGN_START, NULL);
#else
	gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5);
#endif
	gtk_size_group_add_widget(group, widget);
	gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0);
	password->newpassword = gtk_entry_new();
	gtk_entry_set_visibility(GTK_ENTRY(password->newpassword), FALSE);
	gtk_box_pack_start(GTK_BOX(hbox), password->newpassword, TRUE, TRUE, 0);
	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
	/* new password */
	hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
	widget = gtk_label_new("Confirm: ");
#if GTK_CHECK_VERSION(3, 0, 0)
	g_object_set(widget, "halign", GTK_ALIGN_START, NULL);
#else
	gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5);
#endif
	gtk_size_group_add_widget(group, widget);
	gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0);
	password->newpassword2 = gtk_entry_new();
	gtk_entry_set_visibility(GTK_ENTRY(password->newpassword2), FALSE);
	gtk_box_pack_start(GTK_BOX(hbox), password->newpassword2, TRUE, TRUE,
			0);
	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
	/* buttons */
#if GTK_CHECK_VERSION(3, 0, 0)
	hbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
#else
	hbox = gtk_hbutton_box_new();
#endif
	gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END);
	gtk_box_set_spacing(GTK_BOX(hbox), 4);
	widget = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
	g_signal_connect_swapped(widget, "clicked", G_CALLBACK(
				_on_settings_cancel), password);
	gtk_container_add(GTK_CONTAINER(hbox), widget);
	widget = gtk_button_new_from_stock(GTK_STOCK_OK);
	g_signal_connect_swapped(widget, "clicked", G_CALLBACK(_on_settings_ok),
			password);
	gtk_container_add(GTK_CONTAINER(hbox), widget);
	gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
	gtk_container_add(GTK_CONTAINER(password->window), vbox);
	gtk_widget_show_all(password->window);
}

static void _on_settings_cancel(gpointer data)
{
	PasswordPhonePlugin * password = data;

	gtk_widget_hide(password->window);
	gtk_entry_set_text(GTK_ENTRY(password->oldpassword), "");
	gtk_entry_set_text(GTK_ENTRY(password->newpassword), "");
	gtk_entry_set_text(GTK_ENTRY(password->newpassword2), "");
}

static gboolean _on_settings_closex(gpointer data)
{
	PasswordPhonePlugin * password = data;

	gtk_widget_hide(password->window);
	return TRUE;
}

static void _on_settings_ok(gpointer data)
{
	PasswordPhonePlugin * password = data;
	PhonePluginHelper * helper = password->helper;
	GtkWidget * widget;
	char const * name;
	char const * oldpassword;
	char const * newpassword;
	char const * newpassword2;
	ModemRequest request;

	widget = gtk_bin_get_child(GTK_BIN(password->entry));
	name = gtk_entry_get_text(GTK_ENTRY(widget));
	oldpassword = gtk_entry_get_text(GTK_ENTRY(password->oldpassword));
	newpassword = gtk_entry_get_text(GTK_ENTRY(password->newpassword));
	newpassword2 = gtk_entry_get_text(GTK_ENTRY(password->newpassword2));
	if(strcmp(newpassword, newpassword2) != 0)
	{
		_on_settings_ok_error(password,
				"The new passwords do not match");
		return;
	}
	/* issue the request */
	memset(&request, 0, sizeof(request));
	request.type = MODEM_REQUEST_PASSWORD_SET;
	request.password_set.name = name;
	request.password_set.oldpassword = oldpassword;
	request.password_set.newpassword = newpassword;
	helper->request(helper->phone, &request);
	gtk_widget_hide(password->window);
}

static void _on_settings_ok_error(PasswordPhonePlugin * password,
		char const * error)
{
	GtkWidget * dialog;

	dialog = gtk_message_dialog_new(GTK_WINDOW(password->window),
			GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
			GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
#if GTK_CHECK_VERSION(2, 6, 0)
			"%s", "Error");
	gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
#endif
			"%s", error);
	gtk_window_set_title(GTK_WINDOW(dialog), "Error");
	gtk_dialog_run(GTK_DIALOG(dialog));
	gtk_widget_destroy(dialog);
}
