# Rescan.pm by Andrew Hedges (andrew@hedges.me.uk) October 2002
# Timer functions added by Kevin Deane-Freeman (kevindf@shaw.ca) June 2004
# $Id: Rescan.pm 11880 2007-05-01 23:27:36Z mherger $

# This code is derived from code with the following copyright message:
#
# SliMP3 Server Copyright (C) 2001 Logitech
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License,
# version 2.

package Plugins::Rescan;

use strict;
use Slim::Control::Request;
use Slim::Utils::Misc qw(msgf);
use Time::HiRes;

our $interval = 1; # check every x seconds
our @browseMenuChoices;
our %menuSelection;
our %searchCursor;
our %functions;

sub getDisplayName {
	return 'PLUGIN_RESCAN_MUSIC_LIBRARY';
}

sub enabled {
	return ($::VERSION ge '6.1');
}

sub initPlugin {

	%functions = (
		'play' => sub {
			my $client = shift;

			my $valueref = $client->modeParam('valueRef');

			if ($$valueref eq 'PLUGIN_RESCAN_PRESS_PLAY') {

				executeRescan();

				$client->showBriefly( {
					'line' => [ $client->string('PLUGIN_RESCAN_MUSIC_LIBRARY'),
								$client->string('PLUGIN_RESCAN_RESCANNING') ]
				});

			} else {

				$client->bumpRight();
			}
		}
	);

	Slim::Buttons::Common::addMode('scantimer', getFunctions(), \&Plugins::Rescan::setMode);
	setTimer();
}

sub setMode {
	my $client = shift;
	my $method = shift;

	if ($method eq 'pop') {
		Slim::Buttons::Common::popMode($client);
		return;
	}

	@browseMenuChoices = (
		'PLUGIN_RESCAN_TIMER_SET',
		'PLUGIN_RESCAN_TIMER_OFF',
		'PLUGIN_RESCAN_TIMER_TYPE',
		'PLUGIN_RESCAN_PRESS_PLAY',
	);

	# get previous alarm time or set a default
	unless (defined Slim::Utils::Prefs::get("rescan-time")) {

		Slim::Utils::Prefs::set("rescan-time", 9 * 60 * 60 );
	}
	
	my %params = (
		'listRef'        => \@browseMenuChoices,
		'externRef'      => sub {
				my $client = shift;
				my $value  = shift;
				
				if (Slim::Utils::Prefs::get("rescan-scheduled") && $value eq 'PLUGIN_RESCAN_TIMER_OFF') {

					return $client->string('PLUGIN_RESCAN_TIMER_ON');
				} else {
					return $client->string($value);
				}
			},
		'externRefArgs'  => 'CV',
		'header'         => 'PLUGIN_RESCAN_MUSIC_LIBRARY',
		'headerAddCount' => 1,
		'stringHeader'   => 1,
		'callback'       => \&rescanExitHandler,
		'overlayRef'     => sub { 
				if ($_[0] ne 'PLUGIN_RESCAN_PRESS_PLAY') {
					return (undef, Slim::Display::Display::symbol('rightarrow')) 
				}
			},
		'overlayRefArgs' => 'V'
	);
		
	Slim::Buttons::Common::pushMode($client, 'INPUT.List', \%params);
}

sub rescanExitHandler {
	my ($client,$exittype) = @_;
	
	$exittype = uc($exittype);

	if ($exittype eq 'LEFT') {

		Slim::Buttons::Common::popModeRight($client);

	} elsif ($exittype eq 'RIGHT') {
		my $valueref = $client->param('valueRef');
	
		if ($$valueref eq 'PLUGIN_RESCAN_TIMER_SET') {
			my $value = Slim::Utils::Prefs::get("rescan-time");
			
			my %params = (
				'header' => $client->string('PLUGIN_RESCAN_TIMER_SET'),
				'valueRef' => \$value,
				'cursorPos' => 1,
				'pref' => 'rescan-time',
				'callback' => \&settingsExitHandler
			);
			Slim::Buttons::Common::pushModeLeft($client, 'INPUT.Time',\%params);
	
		} elsif ($$valueref eq 'PLUGIN_RESCAN_TIMER_OFF') {
	
			Slim::Utils::Prefs::set("rescan-scheduled", 1);
			$$valueref = 'PLUGIN_RESCAN_TIMER_ON';
			$client->showBriefly( {
				'line1' => $client->string('PLUGIN_RESCAN_TIMER_TURNING_ON'),
			});
			setTimer($client);
	
		} elsif ($$valueref eq 'PLUGIN_RESCAN_TIMER_ON') {
	
			Slim::Utils::Prefs::set("rescan-scheduled", 0);
			$$valueref = 'PLUGIN_RESCAN_TIMER_OFF';
			$client->showBriefly( {
				'line' => [ $client->string('PLUGIN_RESCAN_TIMER_TURNING_OFF') ]
			});
			setTimer($client);
		
		} elsif ($$valueref eq 'PLUGIN_RESCAN_TIMER_TYPE') {
			my $value = Slim::Utils::Prefs::get("rescan-type");
			
			my %params = (
	
				'header' => 'PLUGIN_RESCAN_TIMER_TYPE',
				'headerAddCount' => 1,
				'stringHeader' => 1,
				'listRef' => ['1rescan','2wipedb','3playlist'],
				'externRef' => [qw(SETUP_STANDARDRESCAN SETUP_WIPEDB SETUP_PLAYLISTRESCAN)],
				'stringExternRef' => 1,
				'valueRef' => \$value,
				'cursorPos' => 1,
				'pref' => 'rescan-type',
				'callback' => \&settingsExitHandler,
			);

			Slim::Buttons::Common::pushModeLeft($client, 'INPUT.List',\%params);
		}
	}
}

sub settingsExitHandler {
	my ($client,$exittype) = @_;

	$exittype = uc($exittype);

	if ($exittype eq 'LEFT') {

		Slim::Utils::Prefs::set($client->param('pref'),${$client->param('valueRef')});

		Slim::Buttons::Common::popModeRight($client);

	} elsif ($exittype eq 'RIGHT') {

		$client->bumpRight();

	} else {
		return;
	}
}

sub getFunctions() {
	return \%functions;
}

sub setTimer {
	# timer to check alarms on an interval
	Slim::Utils::Timers::setTimer(0, Time::HiRes::time() + $interval, \&checkScanTimer);
}

sub checkScanTimer {

	my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

	my $time = $hour * 60 * 60 + $min * 60;

	if ($sec == 0) { # once we've reached the beginning of a minute, only check every 60s
		$interval = 60;
	}

	if ($sec >= 50) { # if we end up falling behind, go back to checking each second
		$interval = 1;
	}

	if (Slim::Utils::Prefs::get("rescan-scheduled")) {

		my $scantime =  Slim::Utils::Prefs::get("rescan-time");

		if ($scantime && $time == $scantime) {

			# alarm is done, so reset to find the beginning of a minute
			if ($time == $scantime + 60) {
				$interval = 1;
			}

			executeRescan();

		}
	}
	setTimer();
}

sub executeRescan {
	
	my $rescanType = ['rescan'];
	my $rescanPref = Slim::Utils::Prefs::get('rescan-type') || '';

	if ($rescanPref eq '2wipedb') {
		$rescanType = ['wipecache'];
	} elsif ($rescanPref eq '3playlist') {
		$rescanType = [qw(rescan playlists)];
	}

	if (!Slim::Music::Import->stillScanning()) {

		$::d_scan && msgf("checkScanTimer - initiating scan of type: [%s]\n", $rescanType->[0]);

		Slim::Control::Request::executeRequest(undef, $rescanType);
	}
}

sub setupGroup {

	my %group = (
		PrefOrder => ['rescan-scheduled','rescan-time', 'rescan-type'],
		PrefsInTable => 1,
		GroupHead => Slim::Utils::Strings::string('PLUGIN_RESCAN_MUSIC_LIBRARY'),
		GroupDesc => Slim::Utils::Strings::string('PLUGIN_RESCAN_TIMER_DESC'),
		GroupLine => 1,
		GroupSub => 1,
		Suppress_PrefSub => 1,
		Suppress_PrefLine => 1,
		Suppress_PrefHead => 1
	);
	
	my %prefs = (
		'rescan-scheduled' => {
			'validate' => \&Slim::Utils::Validate::trueFalse,
			'PrefChoose' => Slim::Utils::Strings::string('PLUGIN_RESCAN_TIMER_NAME'),
			'changeIntro' => Slim::Utils::Strings::string('PLUGIN_RESCAN_TIMER_NAME'),
			'options' => {
				'1' => 'ON',
				'0' => 'OFF',
			},
		},

		'rescan-time' => {
			'validate' => \&Slim::Utils::Validate::acceptAll,
			'validateArgs' => [0,undef],
			'PrefChoose' => Slim::Utils::Strings::string('PLUGIN_RESCAN_TIMER_SET'),
			'changeIntro' => Slim::Utils::Strings::string('PLUGIN_RESCAN_TIMER_SET'),

			'currentValue' => sub {
				my $client = shift;
				my $time = Slim::Utils::Prefs::get("rescan-time");
				my ($h0, $h1, $m0, $m1, $p) = Slim::Buttons::Input::Time::timeDigits($client,$time);
				my $timestring = ((defined($p) && $h0 == 0) ? ' ' : $h0) . $h1 . ":" . $m0 . $m1 . " " . (defined($p) ? $p : '');
				return $timestring;
			},

			'onChange' => sub {
				my ($client,$changeref,$paramref,$pageref) = @_;
				my $time = $changeref->{'rescan-time'}{'new'};
				if (defined $time) {
					my $newtime = 0;
					$time =~ s{
						^(\s?0?[0-9]|1[0-9]|2[0-4]):([0-5][0-9])\s*(P|PM|A|AM)?$
					}{
						if (defined $3) {
							$newtime = ($1 == 12?0:$1 * 60 * 60) + ($2 * 60) + ($3 =~ /P/?12 * 60 * 60:0);
						} else {
							$newtime = ($1 * 60 * 60) + ($2 * 60);
						}
					}iegsx;
					Slim::Utils::Prefs::set('rescan-time',$newtime);
				}
			},
		},
		
		'rescan-type' => {
			'validate' => \&Slim::Utils::Validate::acceptAll,
			'optionSort' => 'K',
			'options' => {
				'1rescan'   => Slim::Utils::Strings::string('SETUP_STANDARDRESCAN'),
				'2wipedb'   => Slim::Utils::Strings::string('SETUP_WIPEDB'),
				'3playlist' => Slim::Utils::Strings::string('SETUP_PLAYLISTRESCAN'),
			},
			'PrefChoose' => Slim::Utils::Strings::string('PLUGIN_RESCAN_TIMER_TYPE'),
			'changeIntro' => Slim::Utils::Strings::string('PLUGIN_RESCAN_TIMER_TYPE'),
		}
	);

	return (\%group,\%prefs);
};

sub strings {
	return q^
PLUGIN_RESCAN_MUSIC_LIBRARY
	CS	Aktualizovat informace z hudebního archivu
	DE	Musiksammlung erneut durchsuchen
	EN	Rescan Music Library
	ES	Volver a examinar la biblioteca de música
	FI	Sekoitukseen haluamasi tyylilajit:
	FR	Analyser la collection musicale
	HE	סריקה חוזרת של ספריית המוסיקה
	IT	Ripeti analisi della libreria musicale
	NL	Muziekcollectie opnieuw scannen

PLUGIN_RESCAN_RESCANNING
	CS	Server právě aktualizuje informace z hudebního archivu
	DE	Server durchsucht Ordner ...
	EN	Server now rescanning...
	ES	El servidor está volviendo a examinar...
	FI	Palvelin lukee hakemistojen sisältöä...
	FR	Analyse en cours...
	HE	השרת מבצע סריקה חוזרת...
	IT	Ripetizione analisi in corso...
	NL	Server is nu bezig met opnieuw scannen...

PLUGIN_RESCAN_PRESS_PLAY
	CS	Stiskněte PLAY a aktualizujte informace z  hudebního archivu.
	DE	Drücken Sie PLAY, um das Einlesen zu starten
	EN	Press PLAY to rescan now.
	ES	Pulse PLAY para volver a examinar ahora.
	FI	Paina "PLAY" lukeaksesi hakemiston sisältö nyt.
	FR	Appuyez sur PLAY pour analyser
	HE	לחץ על PLAY (הפעלה) כדי לבצע סריקה חוזרת כעת.
	IT	Premere PLAY per ripetere l'analisi ora.
	NL	Druk op PLAY om nu opnieuw te scannen.

PLUGIN_RESCAN_TIMER_NAME
	CS	Časovač aktualizace
	DE	Automatisches Durchsuchen
	EN	Rescan Timer
	ES	Temporizador para volver a examinar
	FR	Programmation de l'analyse
	HE	קוצב-זמן לסריקה חוזרת
	IT	Timer analisi
	NL	Timer voor opnieuw scannen

PLUGIN_RESCAN_TIMER_SET
	CS	Nastavte čas pravidelné aktualizace
	DE	Startzeit für erneutes Durchsuchen festlegen
	EN	Set Rescan Time
	ES	Establecer hora para volver a examinar
	FR	Heure de l'analyse
	HE	הגדרת קוצב-זמן לסריקה חוזרת
	IT	Imposta ora analisi
	NL	Tijd voor opnieuw scannen instellen

PLUGIN_RESCAN_TIMER_TURNING_OFF
	CS	Vypínám automatickou aktualizaci...
	DE	Automatisches Durchsuchen wird deaktiviert ...
	EN	Turning rescan timer off...
	ES	Desactivando el temporizador para volver a examinar...
	FR	Désactivation de l'analyse...
	HE	מכבה את קוצב-הזמן לסריקה חוזרת...
	IT	Disattivazione timer analisi...
	NL	Timer voor opnieuw scannen wordt uitgezet...

PLUGIN_RESCAN_TIMER_TURNING_ON
	CS	Zapínám automatickou aktualizaci...
	DE	Automatisches Durchsuchen wird aktiviert ...
	EN	Turning rescan timer on...
	ES	Activando el temporizador para volver a examinar...
	FR	Activation de l'analyse...
	HE	מפעיל את קוצב-הזמן לסריקה חוזרת...
	IT	Attivazione timer analisi...
	NL	Timer voor opnieuw scannen wordt aangezet...

PLUGIN_RESCAN_TIMER_ON
	CS	Časovač aktualizace zapnut
	DE	Automatisches Durchsuchen EIN
	EN	Rescan Timer ON
	ES	Temporizador para volver a examinar ACTIVADO
	FR	Analyse activée
	HE	קוצב-זמן לסריקה חוזרת מופעל
	IT	Timer analisi ATTIVATO
	NL	Timer voor opnieuw scannen AAN

PLUGIN_RESCAN_TIMER_DESC
	CS	Můžete zvolit automatickou denní aktualizaci informací z hudebního archivu. Nastavte čas, kdy se má aktualizace provést a volbou ON tuto funkci aktivujte.
	DE	Sie können ihre Musiksammlung automatisch alle 24h durchsuchen lassen. Legen Sie den Zeitpunkt fest und aktivieren Sie 'Automatisches Durchsuchen'.
	EN	You can choose to allow a scheduled rescan of your music library every 24 hours.  Set the time, and set the Rescan Timer to ON to use this feature.
	ES	Se puede optar por permitir que se vuelva a examinar la biblioteca de música de forma programada cada 24 horas. Establezca la hora y el Temporizador para volver a examinar en ACTIVADO para utilizar esta característica.
	FR	Vous pouvez faire en sorte que le SlimServer analyse à nouveau le contenu de votre bibliothèque toutes les 24 heures. Définissez l'heure et activez Programmation de l'analyse pour utiliser cette fonctionnalité.
	HE	באפשרותך לבחור לאפשר סריקה חוזרת מתוזמנת של ספריית המוסיקה שלך מדי 24 שעות. קבע את השעה והגדר את 'קוצב-זמן לסריקה חוזרת' ל'מופעל' כדי להשתמש במאפיין זה.
	IT	È possibile impostare la pianificazione dell'analisi della libreria musicale ogni 24 ore. Per utilizzare questa funzione, è sufficiente impostare l'ora di esecuzione e attivare il timer dell'analisi.
	NL	Je kunt je muziekcollectie elke 24 uur opnieuw laten scannen. Stel de tijd in en zet de 'Timer voor opnieuw scannen' op AAN om deze functie te gebruiken.

PLUGIN_RESCAN_TIMER_OFF
	CS	Časovač aktualizace vypnut
	DE	Automatisches Durchsuchen AUS
	EN	Rescan Timer OFF
	ES	Temporizador para volver a examinar DESACTIVADO
	FR	Analyse désactivée
	HE	קוצב-זמן לסריקה חוזרת כבוי
	IT	Timer analisi DISATTIVATO
	NL	Timer voor opnieuw scannen UIT

PLUGIN_RESCAN_TIMER_TYPE
	DE	Durchsuchmodus
	EN	Rescan Type
	ES	Tipo de volver a examinar
	FR	Type d'analyse
	HE	סוג סריקה חוזרת
	IT	Tipo di analisi
	NL	Type voor opnieuw scannen
^;
}

1;


