#!%PERL% -w

package Vhffs::Panel::Main;
require Exporter;
@ISA    = qw(Exporter);
@EXPORT = qw( display );

use strict;
use utf8;
use POSIX qw(locale_h);
use HTML::Template;
use locale;
use Locale::gettext;
use CGI;
use CGI::Session;
use File::Spec;
use Encode;

use Vhffs::Main;
use Vhffs::User;
use Vhffs::Group;
use Vhffs::Panel::Menu;
use Vhffs::Panel::User;
use Vhffs::Panel::Commons;
use Vhffs::Panel::Admin;

use Vhffs::Panel::Cvs;
use Vhffs::Panel::DNS;
use Vhffs::Panel::Mail;
use Vhffs::Panel::MailingList;
use Vhffs::Panel::Mysql;
use Vhffs::Panel::Pgsql;
use Vhffs::Panel::Repository;
use Vhffs::Panel::Svn;
use Vhffs::Panel::Git;
use Vhffs::Panel::Mercurial;
use Vhffs::Panel::Bazaar;
use Vhffs::Panel::Web;
use Vhffs::Panel::Cron;

=pod

=head1 NAME

Vhffs::Panel::Main - Provides acces to common VHFFS
functionnalities from Vhffs Panel.

=head1 SYNOPSIS

TODO

=head1 METHODS

=cut

=pod

=head2 check_public

    $panel->check_public;

Checks that public area is available, if it's not the case show a message and exits.

=cut

sub check_public {
    my $panel = shift;
    my $vhffs = $panel->{vhffs};
    my $templatedir = $vhffs->get_config->get_templatedir;
    if( $vhffs->get_config->get_panel->{'use_public'} ne 'yes' ) {
        my $template = new HTML::Template( filename => $templatedir.'/panel/main/close.tmpl' );
        $template->param( TEXT_CLOSE    => gettext('Public area not available') );
        $template->param( TEXT_EXPLAIN  => gettext('Public area is not available on this platform.') );

        $panel->light( $template );
	$panel->display;
        exit( 0 );
    }
}

=pod


=head2 is_open

    $panel->is_open;

Return 1 if panel is open, else return 0

=cut

sub is_open {
	my $panel = shift;
	my $vhffs = $panel->{vhffs};
	use Vhffs::Functions;
	return Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'open'} );
}

=pod


=head2 is_public

    $panel->is_public;

Return 1 if public part is enabled, else return 0

=cut

sub is_public {
	my $panel = shift;
	my $vhffs = $panel->{vhffs};
	use Vhffs::Functions;
	return Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'use_public'} );
}

=pod


=head2 use_avatars

    $panel->use_avatars;

Return 1 if either or both users or groups avatars are enabled, else return 0

=cut

sub use_avatars {
	my $panel = shift;
	my $vhffs = $panel->{vhffs};
	use Vhffs::Functions;
	return ( Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'users_avatars'} )
		|| Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'groups_avatars'} ) );
}

=pod


=head2 use_users_avatars

    $panel->use_users_avatars;

Return 1 if users avatars are enabled, else return 0

=cut

sub use_users_avatars {
	my $panel = shift;
	my $vhffs = $panel->{vhffs};
	use Vhffs::Functions;
	return Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'users_avatars'} );
}

=pod


=head2 use_groups_avatars

    $panel->use_groups_avatars;

Return 1 if groups avatars are enabled, else return 0

=cut

sub use_groups_avatars {
	my $panel = shift;
	my $vhffs = $panel->{vhffs};
	use Vhffs::Functions;
	return Vhffs::Functions::strtobool( $vhffs->get_config->get_panel->{'groups_avatars'} );
}

=pod


=head2 check_modo

    $panel->check_modo

Checks that logged in user is admin or moderator. If it is
not the case, show a message and exits.

=cut

sub check_modo {
    my $panel = shift;
    my $user = $panel->{user};
    unless($user->is_moderator || $user->is_admin) {
        $panel->set_title( gettext('Access denied') );
        $panel->add_error( gettext('You are not granted to access this page') );
	$panel->build;
	$panel->display;
	exit 0;
    }
}

=head2

    $panel->check_admin

Check that logged in user is an admin. If it is not
the case, show a message and exits.

=cut

sub check_admin {
    my $panel = shift;
    my $user = $panel->{user};
    unless($user->is_admin) {
        $panel->set_title( gettext('Access denied') );
        $panel->add_error( gettext('You are not granted to access this page') );
        $panel->build;
        $panel->display;
        exit 0;
    }
}

sub list_themes
{
	my $vhffs = shift;
	return -1 unless defined $vhffs;

	my @themes;
	
	my $dir = $vhffs->get_config->get_panel->{'themesdir'};
	return undef unless defined $dir;

	opendir( DIR , $dir) or return -2;
	my @files = readdir( DIR );
	foreach( @files )
	{
		next if( /\./);
		if( -d $dir."/".$_ )
		{
			push @themes , $_;
		}
	}

	closedir( DIR );
	return @themes;
}


sub list_languages
{
	my $vhffs = shift;
	return -1 if( ! defined $vhffs );

    return $vhffs->get_config->get_available_languages;
}



sub select_lang {
    my $self = shift;
    my @langs = $self->{vhffs}->get_config->get_available_languages;
    my $txt = '';
	foreach my $l ( @langs )
	{
		$txt .= "<a href=\"auth.pl?lang=".$l."\"><img src=\"/themes/".$self->{theme}."/images/".$l.".png\" alt=\"".$l."language\"/></a>";
	}
	return $txt;
}


sub new
{
	my $class = ref($_[0]) || $_[0];
	my $this = {};
	$this->{errors} = [];
	$this->{infos} = [];
	$this->{cookies} = [];
	bless( $this, $class );

	my $cgi = new CGI;
	$cgi->charset('UTF-8');
	$this->{cgi} = $cgi;
	$this->{url} = CGI::url();

	my $vhffs = init Vhffs::Main;
	$this->{vhffs} = $vhffs;
	unless( defined $vhffs )  {
		print CGI->header( -type=>'text/html', -charset=>'utf-8' ), 'Unable to open database connection';
		exit 1;
	}

	my $config = $vhffs->get_config;
	$this->{config} = $config;
	my $templatedir = $config->get_templatedir;
	$this->{templatedir} = $templatedir;

	# lang cookie
	my $lang = $cgi->param('lang');
	$this->add_cookie( CGI->cookie( -name=>'language', -value=>$lang, -expires=>'+10y' ) ) if defined $lang;
	$lang = CGI->cookie('language') unless defined $lang;
	$lang = $vhffs->get_config->get_default_language() unless defined $lang;
	$lang = 'en_US' unless defined $lang;
	$this->{lang} = $lang;

	setlocale(LC_ALL, $lang);
	bindtextdomain('vhffs', '%localedir%');
	textdomain('vhffs');

	# theme cookie
	my $theme = $cgi->param('theme');
	$this->add_cookie( CGI->cookie( -name=>'theme', -value=>$theme, -expires=>'+10y' ) ) if defined $theme;
	$theme = CGI->cookie('theme') unless defined $theme;
	$theme = $config->get_panel->{'default_theme'} unless defined $theme;
	$theme = 'vhffs' unless( defined $theme  &&  -f $config->get_panel->{'themesdir'}.'/'.$theme.'/main.css' );
	$this->{theme} = 'vhffs';

	my $template = new HTML::Template( filename => $templatedir.'/panel/main/main.tmpl' );
	$this->{template} = $template;

	if( $vhffs->is_valid() == 0 )
	{
		my $template = new HTML::Template( filename => $templatedir.'/panel/main/close.tmpl' );
		$template->param( TEXT_CLOSE    => gettext("Platform temporary closed<br/>database error") );
		$template->param( TEXT_EXPLAIN  => gettext("This platform is temporary closed. Administrators are performing some maintenances tasks or system has database errors. Please come back in a few minutes to log in.") );
    
		$this->light( $template );
		$this->display;
		exit 0;
	}

	if( $vhffs->get_config->get_panel->{'open'} ne 'yes' )
	{
		$template = new HTML::Template( filename => $templatedir.'/panel/main/close.tmpl' );
		$template->param( TEXT_CLOSE    => gettext("Platform temporary closed.") );
		$template->param( TEXT_EXPLAIN  => gettext("This platform is temporary closed. Administrators are performing some maintenances tasks. Please come back in a few minutes to log in.") );

		$this->light( $template );
		$this->display;
		exit 0;
	}
	
	$this->{is_ajax_request} = (defined $this->{cgi}->http('X-Requested-With')
		and $this->{cgi}->http('X-Requested-With') eq 'XMLHttpRequest');

	return $this;
}



sub get_session
{
	my $panel = shift;
	my $vhffs = $panel->{vhffs};
	my $cgi = $panel->{cgi};

	my $sid = $cgi->cookie( CGI::Session::name() );
	unless( defined $sid )  {
		$panel->add_error( gettext('No cookie found, please accept the cookie and then please login again !') );
		Vhffs::Panel::Commons::display_login( $vhffs, $panel );
		exit 0;
	}

	my $session = new CGI::Session( undef, $sid, {Directory=>'/tmp'} );
	unless( defined $session )  {
		$panel->add_error( gettext('Cannot create or fetch session file, please check that /tmp is readable and writeable') );
		Vhffs::Panel::Commons::display_login( $vhffs, $panel );
		exit 0;
	}

	my $username = $session->param('username');
	my $uid = $session->param('uid');
	unless(  defined $username  &&  defined $uid  &&  !$session->is_new()  )  {
		$panel->add_error( gettext('Expired session ! Please login again') );
		$session->delete();
		Vhffs::Panel::Commons::display_login( $vhffs, $panel );
		exit 0;
	}

	my $user = Vhffs::User::get_by_uid($vhffs, $uid);
	unless ( defined $user )  {
		$panel->add_error( gettext('User does not exist') );
		$session->delete();
		Vhffs::Panel::Commons::display_login( $vhffs, $panel );
		exit 0;
	}

	unless( $user->get_status == Vhffs::Constants::ACTIVATED )  {
		$panel->add_error( gettext('You\'re are not allowed to browse panel') );
		$session->delete();
		Vhffs::Panel::Commons::display_login( $vhffs, $panel );
		exit 0;
	}

	$panel->{session} = $session;
	$panel->{user} = $user;
	Vhffs::Main::current_user_uid($uid);
	return $session;
}


=head2 generate_header

    print $panel->generate_header;

Generates panel header (account name, project label, contextuel menu, etc.).

=cut

sub generate_header {
    my $panel = shift;
    my $user = $panel->{user};
    my $theme = $panel->{theme};
    my $templatedir = $panel->{templatedir};
    my $vhffs = $panel->{vhffs};
    my $cgi = $panel->{cgi};

    my $group = Vhffs::Group::get_by_groupname( $vhffs , $cgi->param('group') );

    my $menutemplate = new HTML::Template( filename => $templatedir.'/panel/menu/main.tmpl' );
    $menutemplate->param( THEME => $theme );

    $menutemplate->param( USERNAME          => $user->get_username() );
    # Sets account type and admin link if needed
    if( $user->is_admin == 1 ) {
        $menutemplate->param( TEXT_ACCOUNT    => gettext('Admin account') );
        $menutemplate->param( TEXT_ADMIN => gettext('Administration') ) 
    } elsif( $user->is_moderator == 1 ) {
        $menutemplate->param( TEXT_ACCOUNT    => gettext('Moderator account') );
        $menutemplate->param( TEXT_ADMIN => gettext('Administration') ) 
    } else {
        $menutemplate->param( TEXT_ACCOUNT    => gettext('User account') );
    }
    $menutemplate->param( TEXT_HOME         => gettext('Home page') );
    $menutemplate->param( TEXT_PREFS        => gettext("User Preferences") );
    $menutemplate->param( TEXT_PROJECTS     => gettext('My Projects') );
    $menutemplate->param( TEXT_HELP         => gettext("Help") );
    $menutemplate->param( TEXT_SUBMITBUG    => gettext("Submit a bug") );
    $menutemplate->param( TEXT_LOGOUT       => gettext("Logout") );
    $menutemplate->param( HELP_URL          => $vhffs->get_config->get_panel->{'url_help'} || 'http://www.vhffs.org/' );

    # Current project stuff (TODO stop handle it in session)
    if( ( CGI::url( -absolute => 1) =~ /^\/admin\// ) || defined $cgi->param('admin_menu')) {
        if( $user->is_admin ) {
            $menutemplate->param( CONTEXTUAL_MENU => Vhffs::Panel::Menu::generate_admin_ctxmenu( $vhffs->get_config ) );
        } elsif( $user->is_moderator ) {
            $menutemplate->param( CONTEXTUAL_MENU => Vhffs::Panel::Menu::generate_moderator_ctxmenu( $vhffs->get_config ) );
        }
    } elsif( $group ) {
        $menutemplate->param( CONTEXTUAL_MENU => Vhffs::Panel::Menu::generate_project_ctxmenu( $vhffs->get_config , $group ) );
    }


    return $menutemplate->output();
}

sub has_errors
{
    my $panel = shift;
    return (@{$panel->{errors}} > 0);
}

sub set_title
{
    my ($panel, $title) = @_;
    $panel->{title} = $title;
}

sub add_error
{
    my ($panel, $error) = @_;
    push(@{$panel->{errors}}, {msg => $error});
}

sub add_info
{
    my ($panel, $info) = @_;
    push(@{$panel->{infos}}, {msg => $info});
}

sub add_cookie
{
    my ($panel, $cookie) = @_;
    push(@{$panel->{cookies}}, $cookie);
}

sub clear_infos
{
    my $panel = shift;
    $panel->{infos} = [];
}

sub welcome
{
	my $panel = shift;
	my $vhffs = $panel->{'vhffs'};
	my $user = $panel->{'user'};
	my $templatedir = $panel->{'templatedir'};

	$panel->set_title( sprintf( gettext('Hello %s, welcome in VHFFS !'), $user->get_username() ) );

	my $template = new HTML::Template( filename => $templatedir.'/panel/misc/welcome.tmpl' );
	$template->param( TEXT_WELCOME => gettext('If you are new to VHFFS, you should start to read quickly the whole help available by clicking on the help button in the upper right of your screen') );

	# check groups quota
	my @overquota;
	foreach my $group ( @{$user->get_groups} )  {
		my $quota = $group->get_quota;
		my $curused = $group->get_quota_used;
		if( $curused > $quota-$quota/10 )  {
			my %g = ( groupname => $group->get_groupname );
			push @overquota, \%g;
		}
	}
	if( @overquota )  {
		$template->param( OVER_QUOTA_TEXT => gettext('The following projects have reached or are going to reach the disk quota limit, please take a look !') );
		$template->param( OVER_QUOTA => \@overquota );
	}

	return $template;
}


sub project_info
{
	my $panel = shift;
	my $vhffs = $panel->{vhffs};
	my $cgi = $panel->{cgi};
	my $templatedir = $vhffs->get_config->get_templatedir;
	my $temp;
	my $object;
	my $objects;
	my $template;
	my $subtemplate;

	my $group = Vhffs::Group::get_by_groupname( $vhffs , $cgi->param('group') );
		
    if( ! defined( $group ) ) {
        $template = new HTML::Template( filename => $templatedir."/panel/misc/simplemsg.tmpl" );
        $template->param( MESSAGE  => gettext("Group error" ) );
    } else {
        $template = new HTML::Template( filename => $templatedir."/panel/group/info.tmpl" );
        $panel->set_title( sprintf( gettext("Group %s") , $group->get_groupname ) );
        $template->param( THEME => $panel->{theme} );

        # Quota stuff
        $template->param( QUOTA_TEXT => sprintf( gettext("Quota (used/total) : %s/%s") , $group->get_quota_used , $group->get_quota ) );
        # Yes, sorry quota progress image has to be 300px width max
        $template->param( QUOTA_WIDTH => ( ($group->get_quota_used / $group->get_quota) * 300 ) );

        my $gid = $group->get_gid;
        my $config = $vhffs->get_config;
        my $services_list = '';

        $template->param( TEXT_PREFS => gettext('Preferences') );
        $template->param( TEXT_GENERAL => gettext('General') );
        $template->param( TEXT_FULLHISTORY => gettext('Full history') );

        $template->param( GROUPNAME => $group->get_groupname );

	my $groupconfig = $config->get_groups;
	if( defined $groupconfig && defined ( my $url = $groupconfig->{'url_doc'} ) )  {
		$template->param( HELP_TEXT => gettext('Help') );
		$template->param( HELP_URL => $url );
	}

        if($config->get_service_availability('web')) {
            my $webs = Vhffs::Panel::Web::getall_per_group( $vhffs, $gid );
            $services_list .= $panel->create_service_index('web', $webs)->output;
        }

        if($config->get_service_availability('mysql')) {
            my $mysql = Vhffs::Panel::Mysql::getall_per_group( $vhffs, $gid );
            $services_list .= $panel->create_service_index('mysql', $mysql)->output;
        }

        if($config->get_service_availability('pgsql')) {
            my $pg = Vhffs::Panel::Pgsql::getall_per_group( $vhffs, $gid );
            $services_list .= $panel->create_service_index('pgsql', $pg)->output;
        }

        if($config->get_service_availability('cvs')) {
            my $cvs = Vhffs::Panel::Cvs::getall_per_group( $vhffs, $gid );
            $services_list .= $panel->create_service_index('cvs', $cvs)->output;
        }

        if($config->get_service_availability('svn')) {
            my $svn = Vhffs::Panel::Svn::getall_per_group( $vhffs, $gid );
            $services_list .= $panel->create_service_index('svn', $svn)->output;
        }

        if($config->get_service_availability('git')) {
            my $git = Vhffs::Panel::Git::getall_per_group( $vhffs, $gid );
            $services_list .= $panel->create_service_index('git', $git)->output;
        }

        if($config->get_service_availability('mercurial')) {
            my $mercurial = Vhffs::Panel::Mercurial::getall_per_group( $vhffs, $gid );
            $services_list .= $panel->create_service_index('mercurial', $mercurial)->output;
        }

        if($config->get_service_availability('bazaar')) {
            my $bazaar = Vhffs::Panel::Bazaar::getall_per_group( $vhffs, $gid );
            $services_list .= $panel->create_service_index('bazaar', $bazaar)->output;
        }

        if($config->get_service_availability('mailinglist')) {
            my $ml = Vhffs::Panel::MailingList::getall_per_group( $vhffs, $gid );
            $services_list .= $panel->create_service_index('mailinglist', $ml)->output;
        }

        if($config->get_service_availability('mail')) {
            my $mail = Vhffs::Panel::Mail::getall_per_group( $vhffs, $gid );
            $services_list .= $panel->create_service_index('mail', $mail)->output;
        }

        if($config->get_service_availability('repository')) {
            my $repos = Vhffs::Panel::Repository::getall_per_group( $vhffs, $gid );
            $services_list .= $panel->create_service_index('repository', $repos)->output;
        }

        if($config->get_service_availability('dns')) {
            my $dns = Vhffs::Panel::DNS::getall_per_group( $vhffs, $gid );
            $services_list .= $panel->create_service_index('dns', $dns)->output;
        }

        if($config->get_service_availability('cron')) {
            my $cron = Vhffs::Panel::Cron::getall_per_group( $vhffs, $gid );
            $services_list .= $panel->create_service_index('cron', $cron)->output;
        }

        $template->param( SERVICES => $services_list );
	}
	return $template;
}


sub set_refresh_url
{
	my ( $panel , $url , $time ) = @_;

	if( defined $url )  {
		my $template = $panel->{template};
		$template->param( REFRESH_URL => $url );
		$template->param( REFRESH_TIME => $time || 3 );
	}
	return;
}


sub build
{
	my $panel = shift;
	my $template = shift;
	my $cgi = $panel->{cgi};
	my $theme = $panel->{theme};
	my $templatedir = $panel->{templatedir};

	$panel->add_info( Encode::decode_utf8( $cgi->param('msg') ) ) if( defined $cgi->param('msg') );
	$panel->add_error( Encode::decode_utf8( $cgi->param('error') ) ) if( defined $cgi->param('error') );

	my $paneltemplate = new HTML::Template( filename => $templatedir.'/panel/main/panel.tmpl' );
	$paneltemplate->param( TITLE => $panel->{title} );
	$paneltemplate->param( HEADER => $panel->generate_header );

	if( @{$panel->{errors}} > 0 ) {
		my $tmplerrors = new HTML::Template( filename => $templatedir.'/panel/misc/errors.tmpl' );
		$tmplerrors->param( ERRORS => $panel->{errors} );
		$paneltemplate->param( ERRORS => $tmplerrors->output );
	}

	if( @{$panel->{infos}} > 0 ) {
		my $tmplinfos = new HTML::Template( filename => $templatedir.'/panel/misc/infos.tmpl' );
		$tmplinfos->param( INFOS => $panel->{infos} );
		$paneltemplate->param( INFOS => $tmplinfos->output );
	}

	$paneltemplate->param( CONTENT => $template->output ) if( defined $template );

	$panel->{content} = $paneltemplate->output;
	return;
}


sub light
{
	my $panel = shift;
	my $template = shift;
	my $cgi = $panel->{cgi};
	my $theme = $panel->{theme};
	my $templatedir = $panel->{templatedir};

	$panel->add_info( Encode::decode_utf8( $cgi->param('msg') ) ) if( defined $cgi->param('msg') );

	$template->param( THEME => $theme ) if( ($template->query(name => 'THEME') || '') eq 'VAR' );

	if( @{$panel->{errors}} > 0 ) {
		my $tmplerrors = new HTML::Template( filename => $templatedir.'/panel/misc/errors.tmpl' );
		$tmplerrors->param( ERRORS => $panel->{errors} );
		$template->param( ERRORS => $tmplerrors->output );
	}

	if( @{$panel->{infos}} > 0 ) {
		my $tmplinfos = new HTML::Template( filename => $templatedir.'/panel/misc/infos.tmpl' );
		$tmplinfos->param( INFOS => $panel->{infos} );
		$template->param( INFOS => $tmplinfos->output );
	}

	$panel->{content} = $template->output;
	return;
}


sub display
{
	my $panel = shift;
	my $template = $panel->{'template'};
	my $cgi = $panel->{cgi};
	my $theme = $panel->{theme};
	my $config = $panel->{config};

	$template->param( TITLE => sprintf( gettext( '%s\'s Panel' ), $config->get_host_name ) );
	$template->param( THEME => $theme );

	# Allow each theme to have its own Jscripts
	my $jsglob = File::Spec->catfile($config->get_panel->{'themesdir'}, $theme, '/js/*.js');
	my $jswebpath = '/themes/'.$theme.'/js/';
	my @jscripts;
	# Common scripts
	push @jscripts, {SCRIPT => '/js/prototype.js'};
	push @jscripts, {SCRIPT => '/js/commons.js'};
	push @jscripts, {SCRIPT => '/js/tooltip.js'};
	while( glob($jsglob) ) {
		use File::Basename;
		push @jscripts, {SCRIPT => $jswebpath.basename( $_ )};
	}
	$template->param( JSCRIPTS => \@jscripts );

	$template->param( CONTENT => $panel->{content} );

	binmode STDOUT , ':utf8';
	print CGI->header( -cookie=>[ @{$panel->{cookies}} ], -type=>'text/html', -charset=>'utf-8' );
	print $template->output;
	return;
}


=pod

=head2 redirect

    $panel->redirect($page, $cookies);

Issues a redirection header sending to $page
(you can specify additional cookies to be sent).

This function never returns.

B<C<$page> should be an absolute path>

B<C<$cookies>> can be a CGI::Cookie or a reference
to a CGI::Cookie array.

=cut
sub redirect {
    my ($panel, $dest, $cookies) = @_;

    $dest = Encode::encode_utf8( $dest );

    if(defined $cookies) {
        if(ref($cookies)) {
            foreach(@$cookies) {
                print "Set-Cookie: $_\n";
            }
        } else {
            print "Set-Cookie: $cookies\n";
        }
    }
    print CGI::redirect($dest);
    exit(0);
}

=pod

=head2 create_service_index

    my $webs = Vhffs::Panel::Web::get_per_group($main, $gid);
    my $template = $panel->create_service_index('web', $webs);
    print $template->output;

Generates summary information for a given service using service_index.tmpl.

=cut

sub create_service_index($$$) {
    my ($panel, $service, $services) = @_;
    my %service_labels = (
        cvs => 'CVS repositories',
        dns => 'Domain names',
        mail => 'Mail domains',
        mailinglist => 'Mailing lists',
        mysql => 'MySQL DBs',
        pgsql => 'PostgreSQL DBs',
        repository => 'Download repositories',
        svn => 'SVN repositories',
        git => 'Git repositories',
        mercurial => 'Mercurial repositories',
        bazaar => 'Bazaar repositories',
        web => 'Webareas',
	cron => 'Cron jobs',
    );

    my $vhffs = $panel->{'vhffs'};
    my $cgi = $panel->{'cgi'};
    my $templatedir = $panel->{templatedir};

    my $group = Vhffs::Group::get_by_groupname( $vhffs , $cgi->param('group') );

    my $svclabel = $service_labels{$service};
    my $template = new HTML::Template( filename => $templatedir.'/panel/misc/service_index.tmpl', global_vars => 1 );

    my $format = sprintf( '%s for %%s', $svclabel );
    $template->param( TEXT_TITLE => sprintf(gettext($format), $group->get_groupname) );
    $template->param( SERVICE => $service );
    $template->param( ADMIN_TEXT => gettext('Go to administration') );
    $template->param( RESUBMIT_TEXT => gettext('Propose a new description') );
    $template->param( DELETE_TEXT => gettext('Delete') );
    $template->param( HISTORY_TEXT => gettext('History') );
    $template->param( NEW => gettext('New') );
    $template->param( NO_SERVICE_TEXT => gettext('None') );
    $template->param( SERVICES => $services);
    $template->param( GROUPNAME => $group->get_groupname );

    my $serviceconfig = $vhffs->get_config->get_service($service);
    if( defined $serviceconfig && defined ( my $url = $serviceconfig->{'url_doc'} ) )  {
        $template->param( HELP_TEXT => gettext('Help') );
        $template->param( HELP_URL => $url );        
    }

    return $template;
}

sub format_description($) {
    use CGI qw{escapeHTML};
    my $description = shift;
    $description = escapeHTML($description);
    $description =~ s!\n!<br/>!g;
    return $description;
}

1;
