#!/usr/bin/perl -w

use strict;
use warnings;

my $ConfDir = '/usr/share/xkblayouts';
my $vkbDir = '/usr/share/scv_layouts';
my $BackupDir = '/usr/var/cache/xkblayouts';
my $rLayout = 'ru';
my %dictlayout = ( 'Finnish, Swedish' => 'fise',
                   'English, Dutch' => 'us' );
my $xkbfile = '/usr/share/X11/xkb/symbols/nokia_vndr/rx-51';
my $cmdgetconf = '/usr/bin/osso-product-info';
my $cmdsetxkb = '/usr/bin/setxkbmap';

my (%symbols, $restmode, $withbackup, $hLayout, $srcvkb, $dstvkb);

die "Must be one arg (hardware layout or restore key\n" if(@ARGV != 1);

$dstvkb = "$vkbDir/";
$srcvkb = "$ConfDir/$rLayout.vkb" if(-e "$ConfDir/$rLayout.vkb");
if($ARGV[0] eq '-d') { # default mode
  if(-e $cmdgetconf) {
    (undef, $_) = split /=/, `$cmdgetconf |grep OSSO_PRODUCT_KEYBOARD`;
    if($_) {
  	  /^\'([^\']+)\'/;
	 	  warn "Default mode for '$1' keyboard\n" if($1);
  	  $hLayout = $dictlayout{$1} if($1);
    }
  }
 	$hLayout = 'fise' unless($hLayout);
} elsif($ARGV[0] eq '-r') { # restore mode
  $restmode = 1;
  while(<$BackupDir/*.layout>) {
    next unless(/\/([^\/|^\.]+)\.layout$/);
    $symbols{$1} = "$_";
  }
  $srcvkb = "$BackupDir/$rLayout.vkb" if(-e "$BackupDir/$rLayout.vkb");
  $dstvkb = "$vkbDir/";
} elsif($ARGV[0] eq '-l') { # list available layout mode
  my $c = 0;
  while(<$ConfDir/*.conf>) {
    next unless(/\/([^\/|^\.]+)\.conf$/);
    $c++;
    open(CONF, "<$_") or die "Can't open for read $_ config file\n";
    print "$1: ". <CONF>;
    close(CONF);
  }
  if($c) {
    print "\n--\nFound $c layouts\n";
  } else {
    print "Layouts not available\n";
  }  
  exit 0;
} else {
  $hLayout = $ARGV[0];
}
if($hLayout) {
  die "Config file for $hLayout layout not found\n" unless(-e "$ConfDir/$hLayout.conf");
  $symbols{$rLayout} = "$ConfDir/$hLayout.conf";
  $withbackup = "$BackupDir/$rLayout.layout" unless(-e "$BackupDir/$rLayout.layout");
}

if($restmode && !%symbols) {
  warn "Nothing to restore\n";
  exit 0;
} else {
  ($_) = keys(%symbols);
  warn "Replace $_ from $symbols{$_}\n";
}

die "Original file $xkbfile not found\n" unless(-e $xkbfile);

open(IN, "<$xkbfile") or die "Can't open for read $xkbfile file\n";
open(OUT, ">$xkbfile.new") or die "Can't create file $xkbfile.new\n";
open(BACKUP, ">$withbackup") or die "Can't open for create $withbackup file\n" if($withbackup);
my $mode = 0;

while(<IN>) {
  if(!$mode && /^xkb_symbols\s+\"([^\"]+)\"/ && $symbols{$1}) {
    print BACKUP $_ if($withbackup);
    if($restmode) {
      open(CONF, "<$symbols{$1}") or die "Can't open for read $symbols{$1} file\n";
      while(<CONF>) { print OUT; }
    } else {
      open(CONF, "<$symbols{$1}") or die "Can't open for read $symbols{$1} file\n";
      chomp($_ = <CONF>);
      print OUT "xkb_symbols \"$1\" { // Modified by package Xkblayouts-rx51-ru\n  name[Group1] = \"$_\";\n\n";
      foreach my $s(split/\s+/, <CONF>) { print OUT "  include \"nokia_vndr/rx-51($s)\"\n"; }
      print OUT "\n  key.type[Group1] = \"EIGHT_LEVEL_SEMIALPHABETIC\";\n\n";
      while(<CONF>) {
        chomp;
        my @s = split/\s+/;
        print OUT "  key \<$s[0]\> { [ " . join(', ', @s[1..6,3,4]) . " ] };\n" if(@s);
      }
      print OUT "};\n\n";
    }
    close(CONF);
    $mode = 1;
    $_ = "";
  }
  unless($mode) {
    print OUT;
  } else {
#		next unless($_);
    print BACKUP $_ if($withbackup);
    ($_) = split/\/\//;
    next if(!$_ || /^\s*$/);
    while(/\{/) { s/\{//; $mode++; }
    while(/\}/) { s/\}//; $mode--; }
  }
}
close(IN);
close(OUT);
close(BACKUP) if($withbackup);
system("mv $xkbfile.new $xkbfile");

if($restmode) {
  foreach $_(keys %symbols) {
    unlink $symbols{$_};
  } 
}
#copy ru.vkb file
if($srcvkb) {
	unless($restmode) {
	  system("cp $vkbDir/$rLayout.vkb $BackupDir/") unless(-e "$BackupDir/$rLayout.vkb");
    warn "Replace virual keyboard with $srcvkb\n";
	}
  system("cp $srcvkb $dstvkb");
  unlink("$BackupDir/$rLayout.vkb") if($restmode && -e "$BackupDir/$rLayout.vkb");
}

#reload Ru layout

if(-e $cmdsetxkb) {
  $_ = `$cmdsetxkb -print |grep xkb_symbols`;
  if(/rx-51\($rLayout\)/) {
    system("$cmdsetxkb -rules evdev -model nokiarx51 -layout $rLayout -variant \",qwerty\"");
    warn "Layout Ru reloaded\n";
  }
}
