#!/usr/bin/php
<?php
/*
 * meg4/misc/unicode.php
 *
 * Copyright (C) 2023 bzt
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * @brief small tool to generate unicode.h
 */

/* download files if they are missing */
$fn = "UnicodeData.txt";
if(!file_exists($fn) || !filesize($fn)) {
    echo("Downloading UNICODE database ".$fn."... ");
    @file_put_contents($fn, @file_get_contents("http://www.unicode.org/Public/UCD/latest/ucd/".$fn));
    if(@filesize($fn) > 0) echo("OK\n"); else { @unlink($fn); die("ERROR!!!\n"); }
}
echo("Parsing uppercase-lowercase UNICODE pairs... ");
foreach(file("UnicodeData.txt") as $line) {
    $l = explode(";",$line);
    $i = hexdec($l[0]); if($i > 65535) break;
    $j = hexdec($l[13]); if(!$j || $j>65535) continue;
    $r[$j-$i][]=$i; $L[$i]=$l[13];
}
$o="/* generated by misc/unicode.php DO NOT edit */\nint unicode_tolower(int a)\n{\n";
$C=[];
foreach($r as $d=>$a) {
    if(count($a)==1) { $C[dechex($a[0])]=/*fuck php, overflow error... $a[0]+$d*/$L[$a[0]]; continue; }
    if($d==-1||$d==1) {
        $o.="    if(!(a&1)&&("; $n = 0;
        for($k = 0; $k < count($a); $k++) {
            if($a[$k]&1) continue;
            for($s = $a[$k]; $k + 1 < count($a) && $a[$k] + 2 == $a[$k+1]; $k++);
            $e=$a[$k];
            $o.=($n?"||":"").($s<$e?"(a>=0x".dechex($s)."&&a<=0x".dechex($e).")":"(a==0x".dechex($s).")");
            $n++;
        }
        $o.=")) return a".($d>0?"+":"").$d.";\n";
        $o.="    if((a&1)&&("; $n = 0;
        for($k = 0; $k < count($a); $k++) {
            if(!($a[$k]&1)) continue;
            for($s = $a[$k]; $k + 1 < count($a) && $a[$k] + 2 == $a[$k+1]; $k++);
            $e=$a[$k];
            $o.=($n?"||":"").($s<$e?"(a>=0x".dechex($s)."&&a<=0x".dechex($e).")":"(a==0x".dechex($s).")");
            $n++;
        }
        $o.=")) return a".($d>0?"+":"").$d.";\n";
    } else {
        $o.="    if("; $n = 0;
        for($k = 0; $k < count($a); $k++) {
            for($s = $a[$k]; $k + 1 < count($a) && $a[$k] + 1 == $a[$k+1]; $k++);
            $e=$a[$k];
            $o.=($n?"||":"").($s<$e?"(a>=0x".dechex($s)."&&a<=0x".dechex($e).")":"(a==0x".dechex($s).")");
            $n++;
        }
        $o.=") return a".($d>0?"+":"").$d.";\n";
    }
}
if(!empty($C)) {
    $o.="    switch(a) {";
    $n=-1;foreach($C as $k=>$v) {
        if($n==3)$n=0;else$n++;
        $o.=(!$n?"\n        ":" ")."case 0x".$k.": return 0x".$v.";";
    }
    $o.="\n    }\n";
}
$o.="    return a;\n}\n";
echo("OK\n");
file_put_contents("../editors/unicode.h", $o);
