<?php
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2008 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.

$lang_language_dir = "../languages/";
$lang_translations_dir = "translations/";
$lang_prj_translations_dir = "project_specific_translations/";
$lang_compiled_dir = "compiled/";
$lang_log_level = 1;

/**
 * Fetches a list of compiled languages from the directory
 * set to contain such files.
 * @returns A list of languages that have been compiled
 */
function getSupportedLanguages(){
    global $lang_language_dir, $lang_compiled_dir;
    $list = array();
    if (is_dir($lang_language_dir.$lang_compiled_dir)) {
        if ($dh = opendir($lang_language_dir.$lang_compiled_dir)) {
            while ($file = readdir($dh)) {
                if (substr($file, -7) != ".po.inc") continue;
                if (is_numeric(substr($file, 0, 5))) continue;
                $list[] = substr($file,0,-7);
            }
        }
    } else {
        echo "\"".$lang_language_dir.$lang_compiled_dir."\" is not a directory. Please consult the documentation for correctly setting up the translation system.";
        exit;
    }
    return $list;
}

/**
 * Builds the lookup arrays from the 
 * language files found in the given directory tree.
 * @param langdir The language base directory
 * @param transdir The location of the .po files to compile relative to langdir
 * @param compdir The output location relative to langdir
 * @param append If true the function will only append to rather than replace the compiled files
 */
function buildLanguages($langdir,$transdir,$compdir){
    global $lang_project_default;

    // Run through each language and compile their lookup arrays.
    if (is_dir($langdir.$transdir)) {
        if ($dh = opendir($langdir.$transdir)) {
            while (($file = readdir($dh)) !== false) {
                if ($file==".." or $file=="."){
                    // Skip parent and current dir
                } else if (substr($file,-3)==".po"){
                    // and only do files ending in .po
                    language_log(
                        "-------------Compiling $transdir$file------------", 0
                    );
                    $language = parseLanguage($langdir.$transdir.$file);
                    if (!$language){
                        language_log(
                            "WARNING: Could not parse language ".$file
                        );
                        continue;
                    }
                    $path = $langdir.$compdir.$file.".inc";
                    if (file_exists($path)) {
                        $fh = fopen($path, "a");
                    } else {
                        $fh = fopen($path, "w");
                        fwrite($fh, "<?php\n");                    
                    }
                    if (!$fh) {
                        language_log(
                            "ERROR: could not access $langdir $compdir - please check permissions", 2
                        );
                        exit;
                    }
                    foreach ($language as $key => $value){
                        if ($value !== "") {
                            //Skip if the msgstr is empty
                            fwrite($fh, "\$language_lookup_array[\"".str_replace("\"", "\\\"", substr($file,0,-3))."\"][\"".$key."\"] = \"".$value."\";\n");
                        }
                    }
                    // don't write \?\> - may append

                    fclose($fh);
                } else {
                    //debug("File $file with unknown extension found in $info_dir");
                }
            }
            closedir($dh);
        } else {
            //debug("$info_dir could not be opened - check permissions?");
        }
    } else {
        //debug("$info_dir not found or is not a directory");
    }
}

/**
 * Parses a gettext .po-file into an associative PHP array.
 * @param file The file to parse
 * checking for inconsistencies if needed.
 *************************/
function parseLanguage($file){
    $translation_file = file($file);
    $first_entry = true;
    $current_token_text="";
    $current_token ="";
    $parsing_token = false;
    $parsing_text = false;
    $output = array();
    for ($i = 0;$i<sizeof($translation_file);$i++){
        $entry = trim($translation_file[$i]);
        //echo "line $i: $entry\n";
        if (substr($entry,0,1)=="#") {
            continue;
        } elseif (strpos($entry, "msgid") !== false) {
            if (!$first_entry){
                //If this is not the first, save the previous entry
                $output[$current_token]=$current_token_text;
            }
            $current_token = getPOLineContent($entry);
            $current_token_text="";
            $parsing_token = true;
            $parsing_text = false;
            $first_entry=false;
        } elseif (strpos($entry, "msgstr") !== false) {
            $current_token_text = getPOLineContent($entry);
            $parsing_token = false;
            $parsing_text = true;
        } elseif ($parsing_token) {
            $current_token .= getPOLineContent($entry);
        } elseif ($parsing_text) {
            $current_token_text.=getPOLineContent($entry);
        }
    }
    
    // Get the last token
    if ($current_token && $current_token_text){
        $output[$current_token]=$current_token_text;
    }
    return $output;
}


/**
 * Returns the contents of a line (ie removes "" from start and end)
 */
function getPOLineContent($line){
    $start = strpos($line, '"')+1;
    $stop = strrpos($line, '"');
    $x =  substr($line, $start, $stop-$start);
    $n = ereg("[^\\]\"", $x);
    if ($n) {
        echo "ERROR - MISMATCHED QUOTES IN $line\n";
        return "";
    }
    return $x;
}

/**
 * Translate string
 */
function tra($text /* ...arglist... */){
    global $language_lookup_array, $languages_in_use;
    
    // Find the string in the user's language
    //
    foreach ($languages_in_use as $language){
        if (isset($language_lookup_array[$language][$text])) {
            $text = $language_lookup_array[$language][$text];
            break;
        } else if ($language=="en"){ 
            // This language is defined in the code and is always available
            break;
        }
    }

    // Replace relevant substrings with given arguments    
    for ($i = 1; $i<func_num_args(); $i++){
        $arg = func_get_arg($i);
        $text = str_replace("%".$i, $arg, $text);
    }
    return $text;
}

function tr_specific($text, $language){
    global $lang_language_dir, $lang_compiled_dir, $language_lookup_array;
    $file_name = $lang_language_dir.$lang_compiled_dir.$language.".po.inc";
    if (file_exists($file_name)) {
        require_once($file_name);
        $text = $language_lookup_array[$language][$text];
    }    
    return $text;
}

function language_log($message, $loglevel=0){
    global $lang_log_level;
    if ($loglevel==0) $msg = "[ Debug    ]";
    if ($loglevel==1) $msg = "[ Warning  ]";
    if ($loglevel==2) $msg = "[ CRITICAL ]";

    if ($loglevel >= $lang_log_level){
        echo date("Y-m-d H:i:s",time())." ".$msg." ".$message."\n";
    }
}

// Make a list of languages which the user prefers
// (by looking at cookies and browser settings)
// cookies have highest priority.

if (isset($_COOKIE['lang'])){
    $language_string = $_COOKIE['lang'].",";
} else {
    $language_string = '';
}
if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) {
    $language_string .= strtolower($_SERVER["HTTP_ACCEPT_LANGUAGE"]);
}

// Find out which language to use by iterating through list
// The list is comma-separated, so split it into an array of the following type:
//        Array (
//    [0] => da
//    [1] => en-us;q=0.7
//    [2] => en;q=0.3
//  )

$client_languages=explode(",",$language_string);

// A language is either defined as primary-secondary or primary.
// It can also have a quality attribute set,
// which orders the languages in a user preferred ordering.
// Since this is usally the same order as the array indices
// we just ignore this attribute (TODO: don't ignore this attribute)
// A missing quality attribute means q=1

$languages_in_use = array();

// Loop over languages that the client requests
for ($i=0; $i<sizeof($client_languages); $i++) {
    if ((strlen($client_languages[$i])>2)
        && (substr($client_languages[$i],2,1)=="_" || substr($client_languages[$i],2,1)=="-"))
    {
        // If this is defined as primary-secondary, represent it as xx_YY
        //
        $language = substr(
            $client_languages[$i],0,2)."_".strtoupper(substr($client_languages[$i],3,2)
        );

        // And also check for the primary language
        //
        $language2 = substr($client_languages[$i],0,2);
    } else {
        // else just use xx
        //
        $language = substr($client_languages[$i],0,2);
        $language2 = null;
    }

    // if main language is english, look no further
    //
    if ($i == 0 && $language == 'en') {
        break;
    }

    // If we have a translation for the language, include it
    $file_name = $lang_language_dir.$lang_compiled_dir.$language.".po.inc";
    if (file_exists($file_name)) {
        if (!in_array($language, $languages_in_use)){
            require_once($file_name);
            $languages_in_use[] = $language;
        }
    }
    if ($language2) {
        $file_name = $lang_language_dir.$lang_compiled_dir.$language2.".po.inc";
        if (file_exists($file_name)) {
            if (!in_array($language2, $languages_in_use)){
                require_once($file_name);
                $languages_in_use[] = $language2;
            }
        }
    }
}

$cvs_version_tracker[]="\$Id: translation.inc 18166 2009-05-19 21:00:03Z boincadm $";  //Generated automatically - do not edit
?>
