#!/bin/bash
# coding=UTF-8
# 
# Copyright (C) 2010 Stefanos Harhalakis
#
# This file is part of activity manager.
#
# activity manager 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 3 of the License, or
# (at your option) any later version.
#
# activity manager 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 activity manager.  If not, see <http://www.gnu.org/licenses/>.
#
# $Id: 0.py 2265 2010-02-21 19:16:26Z v13 $

VERSION="1.1"

D0="$HOME/.activities"

if ! [ -d "$D0" ] ; then
	mkdir "$D0"
fi

cd "$D0"

APPLETBASE="/apps/osso/hildon-desktop/applets"
VIEWSBASE="/apps/osso/hildon-desktop/views"
HHBASE="/apps/osso/hildon-home"
CONTACTS="/apps/osso-addressbook/home-applets"
HOMEPLUGINS="$HOME/.config/hildon-desktop/home.plugins"
THUMBNAILS="$HOME/.bookmarks/home-thumbnails/"

DSTDIR0="activities"
DSCRIPTS0="scripts"

DEFAULTACTIVITY="default"

[ -d "$DSTDIR0" ] || mkdir $DSTDIR0

get_current()
{
	F="$DSTDIR0/current"
	if [ -f "$F" ] ; then
		CURRENT=$(cat "$F")
		if [ -z "$CURRENT" ] || ! [ -d "$DSTDIR0/$CURRENT" ] ; then
			CURRENT=$DEFAULTACTIVITY
		fi
	else
		CURRENT=$DEFAULTACTIVITY
	fi
}

set_current()
{
	F="$DSTDIR0/current"
	echo "$1" > "$F"
}

# Check if "$1" exists as activity
check_exist()
{
	D="$DSTDIR0/$1"
	if [ -d "$D" ]  && [ -e "$D/.activity" ] ; then
		return 0
	else
		return 1
	fi
}

# Check if "$1" exists and report error and exit if it doesn't
check_exist_error()
{
	if ! check_exist "$1" ; then
		echo "No such activity: $1"
		exit 1
	fi
}

is_empty()
{
	if ! check_exist "$1" || ! [ -e "$D/applets.dump" ] ; then
		return 0
	fi
	return 1
}

restart_hildonhome()
{
	echo -n "Restarting hildon-home"

	# First try the gentle approache
	if /usr/sbin/dsmetool -k /usr/bin/hildon-home ; then
		sleep 3
		echo -n "."
		/usr/sbin/dsmetool -t /usr/bin/hildon-home
		echo -n "."
	else
		# But if it fails try the hard one
		killall hildon-home
	fi

	sleep 2
	echo "."
}

# $1 is the activity name
run_scripts_end()
{
	# echo "end $1"

	[ -d "$DSTDIR0/$1" ] || return

	[ -d "$DSCRIPTS0" ] || return

	D="$DSCRIPTS0/$1"

	[ -d "$D" ] || return

	export ACTMAN_ACTIVITY="$1"
	export ACTMAN_WHAT="EXIT"
	run-parts --arg=stop "$D"
	run-parts --arg=stop "$DSCRIPTS0/always"
}

# $1 is the activity name
run_scripts_start()
{
	# echo "start $1"

	[ -d "$DSTDIR0/$1" ] || return

	[ -d "$DSCRIPTS0" ] || return

	D="$DSCRIPTS0/$1"

	[ -d "$D" ] || return

	export ACTMAN_ACTIVITY="$1"
	export ACTMAN_WHAT="ENTER"
	run-parts --arg=start "$DSCRIPTS0/always"
	run-parts --arg=start "$D"
}

save2()
{
	check_exist_error "$CURRENT"

	echo -n "Saving "

	DSTDIR="$DSTDIR0/$CURRENT"
	rm -rf "./$DSTDIR"
	mkdir "$DSTDIR"

	echo -n "."
	# Save bookmarks and shortcuts
	gconftool-2 -g "$HHBASE/bookmark-shortcuts" > $DSTDIR/bookmark-shortcuts
	echo -n "."
	gconftool-2 -g "$HHBASE/task-shortcuts" > $DSTDIR/task-shortcuts
	echo -n "."
	gconftool-2 -g "$CONTACTS" > $DSTDIR/contacts
	echo -n "."
	gconftool-2 --dump "$HHBASE/bookmarks" > $DSTDIR/bookmarks.dump
	echo -n "."
	gconftool-2 --dump "$APPLETBASE" > $DSTDIR/applets.dump
	echo -n "."
	gconftool-2 --dump "$VIEWSBASE" > $DSTDIR/views.dump

	# Save plugins/applets
	[ -e "$HOMEPLUGINS" ] && cp $HOMEPLUGINS "$DSTDIR/home.plugins"

	echo -n "."

	# Save bookmark thumbnails
	if [ -e "$THUMBNAILS" ] ; then
		tar -zcf $DSTDIR/home-thumbnails.tar.gz -C "$THUMBNAILS" .
	fi

	echo -n "."
	touch "$DSTDIR/.activity"

	echo
}

empty()
{
	echo -n "Emptying "

	gconftool-2 --recursive-unset "$APPLETBASE"
	echo -n "."
	[ -e "$HOMEPLUGINS" ] && cat /dev/null > $HOMEPLUGINS
#	gconftool-2 --load "empty/gconf.dump"
	echo -n "."

	gconftool-2 -s --type list --list-type string \
		"$HHBASE/bookmark-shortcuts" "[]"
	echo -n "."
	gconftool-2 -s --type list --list-type string \
		"$HHBASE/task-shortcuts" "[]"
	echo -n "."
	gconftool-2 -s --type list --list-type string \
		"$CONTACTS" "[]"

	# Don't remove thumbnails. Let hildon do it.
	# It is required in order to keep old thumbnails when switching to
	# a new activity or when upgrading to the first version that backs-up
	# thumbnails.
	#echo -n "."
	#[ -e "$THUMBNAILS" ] && ( cd "$THUMBNAILS" && rm -f *.png)

	echo
}

restore2()
{
	check_exist_error "$1"

	get_current

	run_scripts_end "$CURRENT"

	empty

	restart_hildonhome

	SRCDIR="$DSTDIR0/$1"

	if is_empty "$1" ; then
		echo "Empty desktop"
		set_current $1
		return
	fi

	echo -n "Restoring "

	# First load the views - this will be repeated at the end

	gconftool-2 --load $SRCDIR/views.dump

	echo -n "."

	T="$SRCDIR/home-thumbnails.tar.gz"
	if [ -e $T ] ; then
		[ -d "$THUMBNAILS" ] || mkdir "$THUMBNAILS"

		tar -zxf $SRCDIR/home-thumbnails.tar.gz -C $THUMBNAILS
	fi

	echo -n "."

	gconftool-2 --load $SRCDIR/bookmarks.dump

	echo -n "."

	gconftool-2 --load $SRCDIR/applets.dump

	sleep 3
	echo -n "."

	#cp $SRCDIR/home.plugins "$HOME/.config/hildon-desktop/home.plugins"
	if [ -e "$SRCDIR/home.plugins" ] ; then
		cp $SRCDIR/home.plugins "$HOMEPLUGINS"
	else
		rm -f $SRCDIR/home.plugins
	fi

	sleep 2

	echo -n "."

	gconftool-2 -s --type list --list-type string \
		"$HHBASE/bookmark-shortcuts" \
		"$(cat $SRCDIR/bookmark-shortcuts)"

	echo -n "."
	gconftool-2 -s --type list --list-type string \
		"$HHBASE/task-shortcuts" \
		"$(cat $SRCDIR/task-shortcuts)"
	echo -n "."
	gconftool-2 -s --type list --list-type string \
		"$CONTACTS" \
		"$(cat $SRCDIR/contacts)"
	sleep 1

	echo -n "."

	gconftool-2 --load $SRCDIR/applets.dump

	echo -n "."

	gconftool-2 --load $SRCDIR/views.dump

	echo -n "."
	set_current $1

	echo -n "."
	run_scripts_start "$1"

	echo
}

# Store the current activity to "$1"
do_store()
{
	if [ -z "$1" ] ; then
		cat << _KOKO
Pass the activity name to save the current configuration to.
The "current" activity will be also set to be that activity.
If it doesn't exist it will be created.
_KOKO
		exit 1
	fi

	if ! check_exist "$1" ; then
		do_create "$1"
	fi

	echo "Saving to: $1"

	set_current "$1"
	get_current
	save2
}

# Change to "$1" activity
do_change()
{
	if [ -z "$1" ] ; then
		cat << _KOKO
Pass the new activity as the first argument. If it doesn't exist it will
be created.
_KOKO
		exit 1
	fi

	get_current

	if [ "x$CURRENT" != "x" ] && [ "$CURRENT" = "$1" ] ; then
		echo "Already in that activity"
		exit 0
	fi

	check_exist_error "$1"

	echo "Switching activity: $CURRENT -> $1"

	save2
	restore2 "$1"
}

do_list()
{
	(
	FOUND=0
	cd $DSTDIR0
	for i in * ; do
		if [ -d "$i" ] ; then
			echo "$i"
			FOUND=1
		fi
	done
	# If there is no activity, return the default as if it existed
	if [ "$FOUND" = "0" ] ; then
		echo "$DEFAULTACTIVITY"
	fi
	)
}

do_load()
{
	if [ -z "$1" ] ; then
		cat << _KOKO
Pass the new activity as the first argument.
_KOKO
		exit 1
	fi

	if [ "x$1" = "x-f" ] ; then
		ACT="$2"
	else
		ACT="$1"
	fi

	check_exist_error "$ACT"

	get_current

	if [ "x$CURRENT" != "x" ] && [ "$CURRENT" = "$ACT" ] && \
		[ "x$1" != "x-f" ] ; then
		echo "Already in that activity"
		exit 0
	fi

	echo "Switching to activity: $ACT"

	restore2 "$ACT"
}

do_current()
{
	get_current
	echo "$CURRENT"
}

do_create()
{
	if [ -z "$1" ] ; then
		echo "Pass the activity name as the first argument"
		exit 1
	fi

	D="$DSTDIR0/$1"

	if [ -d "$D" ] ; then
		echo "This activity already exists"
		exit 1
	fi

	echo "Creating: $1"

	mkdir "$D"
	touch "$D/.activity"
}

# Common checks for rename and clone
check_rename_clone()
{
	if [ -z "$1" ] || [ -z "$2" ] ; then
		cat << _KOKO
Pass the source and destination name as first and second parameter
repsectively.
_KOKO
		exit 1
	fi

	if ! check_exist "$1" ; then
		echo "Activity $1 doesn't exist"
		exit 1
	fi

	if check_exist "$2" ; then
		echo "Activity $2 already exist"
		exit 1
	fi
}

# Rename $1 to $2
do_rename()
{
	check_rename_clone "$1" "$2"

	get_current

	if [ "$CURRENT" = "$1" ] ; then
		set_current "$2"
	fi

	(
	cd $DSTDIR0
	mv "$1" "$2"
	)
}

do_remove()
{
	if [ -z "$1" ] ; then
		echo "Pass the activity name as the first parameter"
		exit 1
	fi

	if [ "x$1" = "x-f" ] ; then
		ACT="$2"
	else
		ACT="$1"
	fi

	get_current

	if [ "$CURRENT" = "$ACT" ] ; then
		echo "Cannot delete the current activity"
		exit 1
	fi

	check_exist_error "$ACT"

	if ! [ "x$1" = "x-f" ] ; then
		read -p "Are you sure? (type yes to continue) " ans
		if ! [ "$ans" = "yes" ] ; then
			echo "Aborted"
			return
		fi
	fi

	echo "Removing: $ACT"
	(
	cd $DSTDIR0
	rm -rf "$ACT"
	)
}

do_clone()
{
	check_rename_clone "$1" "$2"

	echo "Cloning $1 to $2"

	(
	cd $DSTDIR0
	cp -pR "$1" "$2"
	)
}

do_reload()
{
	get_current

	echo "Reloading activity $CURRENT"

	restore2 "$CURRENT"
}

do_runstart()
{
	if [ "x$1" = "x" ] ; then
		get_current
		ACT="$CURRENT"
	else
		ACT="$1"
	fi

	run_scripts_start "$ACT"
}

do_runend()
{
	if [ "x$1" = "x" ] ; then
		get_current
		ACT="$CURRENT"
	else
		ACT="$1"
	fi

	run_scripts_end "$ACT"
}

do_help()
{
	cat << _KOKO
Activity manager $VERSION

Available commands:

  change DEST		Store current activity and load DEST.
  clone ACT1 ACT2	Create activity ACT2 as a clone of ACT1. Current
  			activity will not be changed.
  create ACTIVITY	Create a new (empty) activity.
  current		Print the current activity name.
  delete [-f] ACTIVITY	Same as remove.
  help			This help.
  list			List available activities.
  load [-f] SRC		Load activity SRC. If -f is used then it will be
  			allowed to re-load the current activity.
  new ACTIVITY		Same as create.
  reload		Reload current activity without storing first.
  remove [-f] ACTIVITY	Remove activity ACTIVITY. If -f is used then there
  			will be no questions asked.
  rename ACT1 ACT2	Rename activity ACT1 to ACT2.
  runstart [ACTIVITY]	Run scripts of entering an activity
  runend [ACTIVITY]	Run scripts of ending an activity
  store DEST		Store current activity as DEST.
  version		Print the version.

Activities are stored under $D0
_KOKO
}

do_version()
{
	echo "$VERSION"
}

case "$1" in
	store)
		do_store "$2"
		;;
	load)
		# Just load
		do_load "$2" "$3"
		;;
	change)
		# Save the current and load the next
		do_change "$2"
		;;
	list)
		do_list
		;;
	current)
		do_current
		;;
	create|new)
		do_create "$2"
		;;
	rename)
		do_rename "$2" "$3"
		;;
	remove|delete)
		do_remove "$2" "$3"
		;;
	clone)
		do_clone "$2" "$3"
		;;
	reload)
		do_reload
		;;
	runstart)
		do_runstart "$2"
		;;
	runend)
		do_runend "$2"
		;;
	help)
		do_help
		;;
	version)
		do_version
		;;
	*)
		echo "Bad command: $1"
		;;
esac

