## -*-mode: Perl;-*-  ;; Have EMACS always use perl-mode for this file.

use strict;
use Cwd;
use Data::Dumper;
use File::Find;

my ($projectName, $majVer, $minVer);
my (@makeVarContent, @content, @allProjectNames);
my $projectRootName = $ARGV[0];
my $installMode = $ARGV[1]; # 0: remove & install all (include, lib, doc)
                            # 1: remove & install include, lib
                            # 2: remove & install doc
                            # 3: remove & install as link include, lib
my $configList = $ARGV[2]; # list of config packages

#------------------
#Get version number
#------------------
open(FILE,"./makeVar") or die "Cannot open file: $!";
@content = <FILE>;
close(FILE);

foreach my $line(@content) {
    if ($line =~ /^TARGET_MAJVERSION:= (\d+)/) {
        $majVer = $1;
    }
    
    if ($line =~ /^TARGET_MINVERSION:= (\d+)/) {
        $minVer = $1;
    }   
}

#---------------------------
#Walk through directory tree
#---------------------------
opendir(DIR,"./") or die "Cannot open DIR: $!";
my @dirs = grep { /ICL/ } readdir(DIR);
closedir(DIR);

my $INSTALLDIR="$ENV{ICL_INSTALL_ROOT}/${projectRootName}/${majVer}.${minVer}";
my $OS_SYSTEM="$ENV{ARCH}";
my $currDir=&Cwd::cwd();

#---- Remove old install tree before installing the new one ----
if ($installMode == 0 || $installMode == 1 || $installMode == 3) {
    print "---- Removing header files in: $INSTALLDIR/include \n";
    system "rm -Rf $INSTALLDIR/include/*.h";
    print "---- Removing example files in: $INSTALLDIR/bin \n";
    system "rm -Rf $INSTALLDIR/bin/*";
    print "---- Removing libraries in: $INSTALLDIR/lib \n";
    system "rm -Rf $INSTALLDIR/lib/*";
    print "---- Removing packages in: $INSTALLDIR/packages \n";
    system "rm -Rf $INSTALLDIR/packages/*";
}

if ($installMode == 0 || $installMode == 2) {
    print "---- Removing docs in: $INSTALLDIR/doc \n";
    system "rm -Rf $INSTALLDIR/doc/*";
}

#---- Create install tree ----
if (!-e "$INSTALLDIR"){
    print "creating directory: $INSTALLDIR\n";
    system "mkdir -p -m 775 $INSTALLDIR";
    system "chmod -R g+w $ENV{ICL_INSTALL_ROOT}/${projectRootName}";
    }

if (!-e "$INSTALLDIR/lib"){
    print "creating directory: $INSTALLDIR/lib\n";
    system "mkdir -p -m 775 $INSTALLDIR/lib";
    }

if (!-e "$INSTALLDIR/bin"){
    print "creating directory: $INSTALLDIR/bin\n";
    system "mkdir -p -m 775 $INSTALLDIR/bin";
    }

if (!-e "$INSTALLDIR/include"){
    print "creating directory: $INSTALLDIR/include\n";
    system "mkdir -m 775 -p $INSTALLDIR/include";
    }

if (!-e "$INSTALLDIR/packages"){
    print "creating directory: $INSTALLDIR/packages\n";
    system "mkdir -p -m 775 $INSTALLDIR/packages";
}

if (!-e "$INSTALLDIR/lib/pkgconfig"){
    print "creating directory: $INSTALLDIR/lib/pkgconfig\n";
    system "mkdir -m 775 -p $INSTALLDIR/lib/pkgconfig";
}

if (!-e "$INSTALLDIR/make"){
    print "creating directory: $INSTALLDIR/make\n";
    system "mkdir -p -m 775 $INSTALLDIR/make";
}

if (!-e "$INSTALLDIR/doc"){
    print "creating directory: $INSTALLDIR/doc\n";
    system "mkdir -p -m 775 $INSTALLDIR/doc";
}

#---- Copy extern projects files----
opendir(DIR,"./packages") or die "Can not open DIR: $!";
my @externPackageList = grep { !/ICL/ && !/\./ } readdir(DIR);
closedir(DIR);

foreach my $externPackage(@externPackageList) {
    #system "cp ./packages/$externPackage $INSTALLDIR/packages";
    system "install -m 664 ./packages/$externPackage $INSTALLDIR/packages/";

    open(FILE,"./packages/$externPackage") or die "Can not open file: ./packages/$externPackage!";
    @makeVarContent = <FILE>;
    close(FILE);

    # create extern package pkgconfig_
    my @extpkgconfigs = ();
    foreach my $line(@makeVarContent) {
        if ($line =~ /^REQUIRES_PKGCONFIG.*/) {
            push(@extpkgconfigs, $line);
        }
    }

    #print "THis is the received config list: -$configList-\n";


    generate_extern_pkgconfig($externPackage, $INSTALLDIR, @extpkgconfigs, $configList);
}

#system "cp ./make/dependencyChecks $INSTALLDIR/make";
#system "install -m 664  ./make/dependencyChecks $INSTALLDIR/make/";
system "install -m 664  ./config $INSTALLDIR/";

#---- Install the whole stuff ----
foreach my $entry(@dirs) {
    #---- Check makeVar for inlcudes ----
    if ($entry !~ /ICLUtils/) {
        open(FILE,"./$entry/makeVar") or die "Can not open file: $entry $!";
        @makeVarContent = <FILE>;
        close(FILE);
    }
    
    my @includes = ();
    foreach my $line(@makeVarContent) {
        if ($line =~ /^include/) {
            push(@includes, $line);
        }
    }
    
    # ---- Install content ----
    if ($installMode == 0 || $installMode == 1) { 
        print "---- Copying header files: $entry/src\n";
#        system "cp ./$entry/src/*.h $INSTALLDIR/include";
        system "install -m 664 ./$entry/src/*.h $INSTALLDIR/include/";
        if ($entry !~ /ICLUtils/) {
            print "---- Copying libraries: $entry/lib\n";
            if ("$OS_SYSTEM" eq "macosx") {
                #system "cp ./$entry/lib/*.dylib $INSTALLDIR/lib";
                #system "cp ./$entry/lib/*.a $INSTALLDIR/lib";
                system "install -m 775 ./$entry/lib/*.dylib $INSTALLDIR/lib";
                system "install -m 775 ./$entry/lib/*.a $INSTALLDIR/lib";
            } else {
#                system "cp -d ./$entry/lib/*.so* $INSTALLDIR/lib";
#                system "cp -d ./$entry/lib/*.a $INSTALLDIR/lib";

                system "install -m 775 ./$entry/lib/*.so* $INSTALLDIR/lib";
                system "install -m 775 ./$entry/lib/*.a $INSTALLDIR/lib";

            }
            
            # ---- Copy examples ----
            print "---- Copying examples: $entry/bin\n";
            opendir(DIR,"./$entry/examples") or die "Can not open DIR: $!";
            my @exampleList = grep { /\.cpp/ } readdir(DIR);
            closedir(DIR);
            foreach my $exampleEntry (@exampleList) {
                $exampleEntry =~ /(^.*)\.cpp/;
#                system "cp ./$entry/examples/$1* $INSTALLDIR/bin";
                system "install -m 775 ./$entry/examples/$1* $INSTALLDIR/bin";
                system "chmod 664 $INSTALLDIR/bin/*.cpp";
            }
        }
    }
    
    # ---- install as link include, lib ----
    if ($installMode == 3) {
        print "---- Linking header files: $entry/src\n";
        system "ln -s $currDir/$entry/src/*.h $INSTALLDIR/include";
        
        if ($entry !~ /ICLUtils/) {
            print "---- Linking libraries: $entry/lib\n";
            if ("$OS_SYSTEM" eq "macosx") {
                system "ln -s $currDir/$entry/lib/*.dylib $INSTALLDIR/lib";
                system "ln -s $currDir/$entry/lib/*.a $INSTALLDIR/lib";
            } else {
                system "ln -s $currDir/$entry/lib/*.so* $INSTALLDIR/lib";
                system "ln -s $currDir/$entry/lib/*.a $INSTALLDIR/lib";
            }

            # ---- link examples ----
            print "---- Linking examples: $entry/bin\n";
            opendir(DIR,"./$entry/examples") or die "Can not open DIR: $!";
            my @exampleList = grep { /\.cpp/ } readdir(DIR);
            closedir(DIR);
            foreach my $exampleEntry (@exampleList) {
                $exampleEntry =~ /(^.*)\.cpp/;
                system "ln -s $currDir/$entry/examples/$1* $INSTALLDIR/bin 2> /dev/null";
            }
        }
        system "chmod -R g+w $INSTALLDIR";
    }
    
    # ---- Install documentation ----
    if ($installMode == 0 || $installMode == 2) {
        print "---- Copying documentation: $entry/doc\n";
        system "cp -r ./$entry/doc/documentation/* $INSTALLDIR/doc/$entry";
        system "chmod -R g+wX $INSTALLDIR/doc";
        system "chmod -R o+rX $INSTALLDIR/doc";
        generate_documentation($INSTALLDIR, @dirs);        
    }

    generate_packagevar($entry, $INSTALLDIR, @includes);
    generate_pkgconfig($entry, $INSTALLDIR, @includes);
    generate_BashSrc($INSTALLDIR);
}

#---------------------
# Remove all .svn dirs
#---------------------
system "find $INSTALLDIR -name '.svn' -exec rm -Rf {} \\; 2> /dev/null";

exit(0);


#----------------------------------------------------------------------------- 
sub generate_documentation {
# {{{ open

    my ($INSTALLDIR, @projects) = @_;
    my $menuTable = "";
    
    #---- Copy static documentation files ----
    system "mkdir -p $INSTALLDIR/doc/html";
    system "cp -r ./doc/html/* $INSTALLDIR/doc/html";
    system "chmod -R g+w $INSTALLDIR/doc";
    
    #---- Generate menu content ----
    @projects = sort(@projects);
    $menuTable .= "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
    $menuTable .= "<html>\n";
    $menuTable .= "<head>\n";
    $menuTable .= "<meta http-equiv=\"Content-Language\" content=\"de\">\n";
    $menuTable .= "<meta http-equiv=\"Content-Type\"\n";
    $menuTable .= "content=\"text/html; charset=windows-1252\">\n";
    $menuTable .= "<title>Menu</title>\n";
    $menuTable .= "<base target=\"Inhalt\">\n";
    $menuTable .= "</head>\n";
    $menuTable .= "<body>\n";
    $menuTable .= "<div align=\"center\">\n";
    $menuTable .= "<table border=\"0\" width=\"100%\" id=\"table1\" bgcolor=\"#C0C0C0\" cellspacing=\"1\" cellpadding=\"0\">\n";
    $menuTable .= "<tr>\n";
    $menuTable .= "<td>\n";
    $menuTable .= "<div align=\"center\">\n";
    $menuTable .= "<table border=\"0\" width=\"100%\" id=\"table2\" bgcolor=\"#C0C0C0\" cellspacing=\"4\" cellpadding=\"0\"\n";
    $menuTable .= "<tr>\n";
    $menuTable .= "<td>\n";
    $menuTable .= "<p align=\"center\"><font color=\"#000080\"><u><b>Main menu</b></u>\n";
    $menuTable .= "</td>\n";
    $menuTable .= "</tr>\n";

    foreach my $project (@projects) {
        $menuTable .= "<tr><td> <a href=\"../".$project."/index.html\" target=\"MainFrame\">".$project."</a></td>\n";
    }

    $menuTable .= "</table>\n";
    $menuTable .= "<br>\n";
    $menuTable .= "</body>\n";
    $menuTable .= "</html>\n";
    
    #---- Write menu.html ----
    open(FILE, ">$INSTALLDIR/doc/html/menu.html") or die "cannot write to menu.html:$!";
    print FILE $menuTable;
    close(FILE);
    chmod(0664,"$INSTALLDIR/doc/html/menu.html");
}

# }}}

sub generate_packagevar {
# {{{ open

    my ($entry, $installdir, @includes) = @_;
    my $pkgContent = "";
    my $ersion = $installdir;

    #---- Generate content ----
    $pkgContent .= "# -*-mode: Makefile;-*-  ;; Have EMACS always use makefile-mode for this file.\n";
    $pkgContent .= "\n";
    $pkgContent .= "#   packageVar\n";
    $pkgContent .= "ifeq \"\${".$entry."_MAKEVAR}\" \"\"\n";
    $pkgContent .= $entry."_MAKEVAR=".$entry."_MAKEVAR\n";
    $pkgContent .= "\n";
    $pkgContent .= "# Please include here the inherited packages\n";
    foreach my $inc (@includes) {
        $inc =~ s/\$\{PACKAGES\}/$installdir\/packages/;
        $pkgContent .= $inc;
    }
    $pkgContent .= "\n";    
    $pkgContent .= "# Please, place here the include directory of the project\n";
    $pkgContent .= "ABS_INCLUDES:= \${ABS_INCLUDES} \\\n";
    $pkgContent .= "-I$installdir/include\n";
    $pkgContent .= "\n";
    $pkgContent .= "# Please, do not change this ifeq statement\n";
    $pkgContent .= "ifeq \"\${AGNI_INHERIT_MODE}\" \"STATIC\"\n";
    $pkgContent .= "\n";
    $pkgContent .= "# Please, place here the static libraries\n";
    $pkgContent .= "ABS_OBJECTS:= \${ABS_OBJECTS} \\\n";
    $pkgContent .= "$installdir/lib/lib".$entry.".a\n";
    $pkgContent .= "\n";
    $pkgContent .= "else\n";
    $pkgContent .= "\n";
    $pkgContent .= "# Please, place here the lib directory of the project and the library name.\n";
    $pkgContent .= "ifeq \"\${OS_TYPE}\" \"linux\"\n";
    $pkgContent .= "ABS_LIBRARIES:= \${ABS_LIBRARIES} \\\n";
    $pkgContent .= "-L".$installdir."/lib -l".$entry." -Wl,-rpath=".$installdir."/lib\n";
    $pkgContent .= "endif\n\n";
    $pkgContent .= "ifeq \"\${OS_TYPE}\" \"macosx\"\n";
    $pkgContent .= "ABS_LIBRARIES:= \${ABS_LIBRARIES} \\\n";
    $pkgContent .= "-L".$installdir."/lib -l".$entry."\n";
    $pkgContent .= "endif\n";
    $pkgContent .= "\n";
    $pkgContent .= "endif\n";
    $pkgContent .= "endif\n";

    #---- Write packagevar ----
    open(FILE, ">$INSTALLDIR/packages/$entry") or die "cannot write packageVar:$!";
    print FILE $pkgContent;
    close(FILE);
    chmod(0664,"$INSTALLDIR/packages/$entry");
}
# }}}

sub generate_BashSrc {
# {{{ open

    my ($installdir) = @_;
    my $BashSrcContent = "";

    #---- Generate content ----
    $BashSrcContent .= "# -*-mode: Makefile;-*-  ;; Have EMACS always use makefile-mode for this file.\n";
    $BashSrcContent .= "\n";
    $BashSrcContent .= "# BashSrc\n";
    $BashSrcContent .= "\n";
    $BashSrcContent .= "PROJECT_NAME=ICL\n";
    $BashSrcContent .= "\n";
    $BashSrcContent .= "FULL_VERSION=".${majVer}.".".${minVer}."\n";
    $BashSrcContent .= "\n";
    $BashSrcContent .= "PROJECT_START_PATH=$ENV{ICL_INSTALL_ROOT}\n";
    $BashSrcContent .= "\n";
    $BashSrcContent .= "EXTRA_LD_LIBRARY_PATH=\"\"\n";
    $BashSrcContent .= "\n";
    $BashSrcContent .= "INHERITED_PROJECTS=\"\${IPP_ROOT}/5.2/BashSrc\"\n";
    $BashSrcContent .= "\n\n";
    $BashSrcContent .= "# --------------------------------------------------\n";
    $BashSrcContent .= "# Do not change anything below this line\n";
    $BashSrcContent .= "# --------------------------------------------------\n";
    $BashSrcContent .= "if ((`echo \${LD_LIBRARY_PATH} | grep -e\"/\${PROJECT_NAME}/\${FULL_VERSION}/\" | wc -c` == 0)); then\n";
    $BashSrcContent .= "\n";
    $BashSrcContent .= "# Run-time libraries paths\n";
    $BashSrcContent .= "export LD_LIBRARY_PATH=\${LD_LIBRARY_PATH}:\${PROJECT_START_PATH}/\${PROJECT_NAME}/\${FULL_VERSION}/lib\n";
    $BashSrcContent .= "\n";
    $BashSrcContent .= "# Extra libraries path  \n";
    $BashSrcContent .= "if [ \"`echo \${EXTRA_LD_LIBRARY_PATH} | wc -m`\" -gt \"1\" ] ; then\n";
    $BashSrcContent .= "  export LD_LIBRARY_PATH=\${LD_LIBRARY_PATH}:\${EXTRA_LD_LIBRARY_PATH}\n";
    $BashSrcContent .= "fi\n";
    $BashSrcContent .= "\n";
    $BashSrcContent .= "# Source all inherited projects\n";
    $BashSrcContent .= "for i in \${INHERITED_PROJECTS} ; do\n";
    $BashSrcContent .= "  source \$i\n";
    $BashSrcContent .= "done\n";
    $BashSrcContent .= "fi\n";

    #---- Write packagevar ----
    open(FILE, ">$installdir/BashSrc") or die "cannot write BashSrc:$!";
    print FILE $BashSrcContent;
    close(FILE);
    chmod(0664,"$installdir/BashSrc");
}

# }}}

sub generate_pkgconfig {
# {{{ open
    
    my ($entry, $installdir, @includes) = @_;
    my ($pkgContent, $requiredList);
    my @dirContent;
    $installdir =~ /^.*\/(\d*.\d*)/;
    my $version = $1;

    foreach my $inc (@includes) {
        $inc =~ /^.*}\/(.*)/;
        $requiredList .= $1." ";
    }
    
    #---- Generate content ----
    $pkgContent .= "# This is the pkg-config file for: $entry\n";
    $pkgContent .= "prefix=$installdir\n";
    $pkgContent .= "\n";
    $pkgContent .= "Name: $entry\n";    
    $pkgContent .= "Version: $version\n";
	$pkgContent .= "Description: ICL Package: $entry\n";
    $pkgContent .= "Requires: $requiredList\n";
    $pkgContent .= "Libs: -L\${prefix}/lib -l$entry\n";
    $pkgContent .= "Cflags: -I\${prefix}/include\n";

    #---- Write pkg-config file ----
    open(FILE, ">$INSTALLDIR/lib/pkgconfig/$entry.pc") or die "cannot write pkgconfig file:$!";
    print FILE $pkgContent;
    close(FILE);
    chmod(0664,"$INSTALLDIR/lib/pkgconfig/$entry.pc");
}

# }}}

sub generate_extern_pkgconfig {
# {{{ open
    
    my ($entry, $installdir, @extpkgconfigs) = @_;
    my ($pkgContent, $requiredList);
    my @dirContent;
    $installdir =~ /^.*\/(\d*.\d*)/;
    my $version = $1;
 
    #print "entry is here -$entry-\n";
    #print "configList here is -$configList-\n";

    if( $configList =~ /.*\[$entry\].*/ ){
        foreach my $ext (@extpkgconfigs) {
            if( $ext =~ /^REQUIRES_PKGCONFIG:=(.*)/ ){
                $requiredList .= $1." ";
            }
        }
    }else{
        #print "skipping entry $entry\n";
    }
    
    #---- Generate content ----
    $pkgContent .= "# This is the pkg-config file for: $entry\n";
    $pkgContent .= "prefix=\n";
    $pkgContent .= "\n";
    $pkgContent .= "Name: $entry\n";    
    $pkgContent .= "Version: $version\n";
    $pkgContent .= "Description: External ICL Package: $entry\n";
    $pkgContent .= "Requires: $requiredList\n";
    $pkgContent .= "Libs: \n";
    $pkgContent .= "Cflags: \n";

    #---- Write pkg-config file ----
    open(FILE, ">$INSTALLDIR/lib/pkgconfig/$entry.pc") or die "cannot write pkgconfig file:$!";
    print FILE $pkgContent;
    close(FILE);
    chmod(0664,"$INSTALLDIR/lib/pkgconfig/$entry.pc");
}

# }}}