# andreas@schosemail.de

use Win32;
use Win32::OLE;
use Win32::OLE::Const('Citrix MetaFrame COM Library');
use Win32::GUI;
use Win32::GUI::Grid;
#use Win32::GUI::Combobox;


sub GetSessions;

$APPNAME = 'GetClientSessions';
$VER = '0.1';
$ICONPATH = 'cscmc.ico';

# these are also important (i geuss) but i don't know why 
my $screen_width = Win32::GUI::GetSystemMetrics(0); 
my $screen_height = Win32::GUI::GetSystemMetrics(1); 

# set the constants used for the dimensions of your box 
my $minwidth = 700; 
my $minheight = 480; 

my $dbv_icon = new Win32::GUI::Icon($ICONPATH);
 
my $dbv_class = new Win32::GUI::Class( 
          -name => "My Funky Class", 
          -icon => $dbv_icon, 
); 


# hopefully this is self explanitory 
my $Font= new Win32::GUI::Font (-name => "Courier",     -height => 10,    -bold  => 0,);

$GUIWindow = new Win32::GUI::Window( 
        -name   => "GUIWindow", 
        # orientation, where the window starts 
        -top    => ($screen_width - $minwidth)/2, 
        -left   => ($screen_height - $minheight)/2, 
        # taken from the constants above ... these are the dimensions o 
        -width  => $minwidth, 
        -height => $minheight, 

        -title  => $APPNAME. ' '. $VER, 

        # make a little icon (notes above) 
        -class  => $dbv_class,
        -font => $Font,
); 

$GUIWindow->AddButton ( 
                -name   => "GUICancel",           
                -left   => 595,  
                -top    => 30,
                -width  => 90, 
                -height => 30,
                -text   => 'Cancel',
        );

$GUIWindow->AddButton (
                -name   => "GUIExportExcel",           
                -left   => 270,  
                -top    => 30,
                -width  => 160, 
                -height => 30,
                -text   => 'Export to Excel',
        );


$GUIWindow->AddButton ( 
                -name   => "GUIRefresh",           
                -left   => 5,  
                -top    => 30,
                -width  => 90, 
                -height => 30,
                -text   => 'Refresh',
        );

@sessioninfos = GetSessions();
$tmp = @sessioninfos + 1; # get length of array

my $GUIGrid = $GUIWindow->AddGrid (
    -name    => "GUIGrid",
    -pos     => [5, 80], #x,y
    -rows    => $tmp,
    -columns => 7,
    -fixedrows    => 1,
    -fixedcolumns => 1,
    -editable => 0,
) or die "new Grid";

#$Font= new Win32::GUI::Font (-name => "Courier",     -height => 10,    -bold  => 1);


$GUIGrid->SetCellText(0, 1,"Username");
$GUIGrid->SetCellText(0, 2,"ClientIP");
$GUIGrid->SetCellText(0, 3,"ClientName");
$GUIGrid->SetCellText(0, 4,"KBytesSend");
$GUIGrid->SetCellText(0, 5,"KBytesRev");
$GUIGrid->SetCellText(0, 6,"KBytesAll");
#$Font= new Win32::GUI::Font (-name => "Courier",     -height => 10,    -bold  => 0);

my $n = 1;
foreach my $session (@sessioninfos) {
    # split at '&&&'
    @strtmp = split('&&&',$session);
    $GUIGrid->SetCellText($n, 1,$strtmp[0]); # Username
    $GUIGrid->SetCellText($n, 2,$strtmp[1]); # ClientIP
    $GUIGrid->SetCellText($n, 3,$strtmp[4]); # ClientName
#    $GUIGrid->SetCellText($n, 4, $strtmp[2] ); # BytesSend
#    $GUIGrid->SetCellText($n, 5, $strtmp[3] ); # BytesRecv
    $GUIGrid->SetCellText($n, 4, int ($strtmp[2] / 1024)); # BytesSend
    $GUIGrid->SetCellText($n, 5, int ($strtmp[3] / 1024)); # BytesRecv

    $GUIGrid->SetCellText($n, 6, int (($strtmp[2] + $strtmp[3]) / 1024 ) ); # BytesAll
#    $GUIGrid->SetCellText($n, 6, int (($strtmp[2] + $strtmp[3]) ) ); # BytesAll
    
    $n++
    #$texto->insert("end", $strtmp[0] ."\t" . $strtmp[1]. "\t". $strtmp[4] ."\t". int ($strtmp[2] / 1024) ."\t" . int ($strtmp[3] / 1024 ). "\t" . int (($strtmp[2] + $strtmp[3]) / 1024 ) . "\n", ['normal']);
}

# Resize Grid Cell
$GUIGrid->SortNumericCells(5, 0);
#$GUIGrid->SortNumericCells(5, 1);
$GUIGrid->AutoSize();
#$GUIGrid->ExpandRowsToFit ();

$GUIWindow->Show(); 
Win32::GUI::Dialog();

sub GUIWindow_Resize {
  my ($width, $height) = ($GUIWindow->GetClientRect)[2..3];
  $GUIGrid->Resize ($width, $height);
}


sub GUIExportExcel_Click {
    
    # use existing instance if Excel is already running
    eval {$ex = Win32::OLE->GetActiveObject('Excel.Application')};
    die "Excel not installed" if $@;
    unless (defined $ex) {
        $ex = Win32::OLE->new('Excel.Application', sub {$_[0]->Quit;})
                or die "Oops, cannot start Excel";
    }
  
    $ex->{Visible} = 1; 
    # get a new workbook
    $book = $ex->Workbooks->Add;
  
    # write to a particular cell
    $sheet = $book->Worksheets(1);

    my $n = 1;
    my $i = 2;
    
    $sheet->Cells($n,$i + 1)->{Value} = 'Username';
    $sheet->Cells($n,$i + 2)->{Value} = 'ClientIP';
    $sheet->Cells($n,$i + 3)->{Value} = 'ClientName';
    $sheet->Cells($n,$i + 4)->{Value} = 'KBytesSend';
    $sheet->Cells($n,$i + 5)->{Value} = 'KBytesRev';
    $sheet->Cells($n,$i + 6)->{Value} = 'KBytesAll';

    $n++;
    
    foreach my $session (@sessioninfos) {
        # split at '&&&'
        @strtmp = split('&&&',$session);
        $sheet->Cells($n,$i + 1)->{Value} = $strtmp[0];
        $sheet->Cells($n,$i + 2)->{Value} = $strtmp[1];
        $sheet->Cells($n,$i + 3)->{Value} = $strtmp[4];
        $sheet->Cells($n,$i + 4)->{Value} = int ($strtmp[2] / 1024);
        $sheet->Cells($n,$i + 5)->{Value} = int ($strtmp[3] / 1024);
        $sheet->Cells($n,$i + 6)->{Value} = int (($strtmp[2] + $strtmp[3]) / 1024);
        $n++;
     }


}


sub GUIGrid_Click {
  my ($col, $row) = @_;

    # sort textvalues
    if ( ($col == 0) && ($row > 3) )   {

        $tmp = $GUIGrid->GetSortAscending(); 
        if ($tmp == 0 ) {
          $GUIGrid->SortNumericCells($row, 1);    
        } elsif ($tmp == 1) {
          $GUIGrid->SortNumericCells($row, 0);
          }
        $GUIGrid->AutoSize();
    }    

    # sort integers (Bytes)
    if ( ($col == 0) && ($row < 4) )   {

        $tmp = $GUIGrid->GetSortAscending(); 
        if ($tmp == 0 ) {
          $GUIGrid->SortTextCells($row, 1);    
        } elsif ($tmp == 1) {
          $GUIGrid->SortTextCells($row, 0);
          }
        $GUIGrid->AutoSize();
    }    
}

sub GUIRefresh_Click {
    print "Refresh function";
}


sub GUICancel_Click {
    print "You hit the Cancel Button";
    exit(0);
}

sub GUIWindow_Terminate { 
    exit (0); 
}

#sub GetSessions_DEV {

#            push @myInfo, 'Andreas.Roth1&&&10.10.10.1&&&123456&&&123456&&&andreasseinlap1';
#            push @myInfo, 'Andreas.Roth2&&&10.10.10.2&&&123456&&&123457&&&andreasseinlap2';
#            push @myInfo, 'Andreas.Roth3&&&10.10.10.3&&&123456&&&123458&&&andreasseinlap3';
#            push @myInfo, 'Andreas.Roth4&&&10.10.10.4&&&123456&&&123459&&&andreasseinlap4';
    
#    return @myInfo;
#}


sub GetSessions {
    ##Creating the farm object
   my $farm = new Win32::OLE("MetaFrameCOM.MetaFrameFarm") || die "Couldtn't create an object\n";
    
    ##Intializing the farm Object
   $farm->Initialize(MetaFrameWinFarmObject);
    
    ## Print the farm name
    print "\nzeige aktive Sessions:\n" ;
    print "----------------------\n" ;
    print "Farmname: " . $farm->FarmName ."\n\n" ;
    
    my $sessions = $farm->Sessions;
    foreach $se (in $sessions) {
        if (($se->ClientAddress ne "") &&  ($se->SessionState == 1)){
            
            $session = new Win32::OLE("MetaFrameCOM.MetaFrameSession");
            $session->Initialize(6, $se->ServerName, $se->SessionName, $se->SessionID);
            #$session->Initialize(6, "", "", -1);
            if (Win32::OLE->LastError() != 0) {
                print "Couldn't create a session object \n";
                print Win32::OLE->LastError();
                exit 0;
            }
                    
            push @myInfo, $session->UserName .'&&&'. $session->ClientAddress .'&&&'. $session->BytesSentPostCompression .'&&&'. $session->BytesRcvdPreExpansion .'&&&' . $session->ClientName;
        }
    }
    
    return @myInfo;
}

