<?php

class NumberCanonizer
{

    function getCountryCode($where = array())
    {
        return NULL;
    }

    function getAreaCode($where)
    {
        return NULL;
    }

    function ___formate_tele_number($number, $countryprefix = "49")
    {
        if (empty($number) || ($number == "")) {
            // very hot working :D
            return null;
        }

        /**
         * rauswahl, Nummernlnaegenglaubhaftigkeit pruefen
         * sonst eine interne Nummer
         */
        if (strcasecmp(substr($tnum, 0, 1), "0") == 0) {
            $tnum = $number;
            $tmp = substr($tnum, 0, 1);

            while ($tmp == '0') {
                // endlos breaker
                if (strlen($tnum) == 0) {
                    break;
                }

                $tnum = substr($tnum, 1);
                $tmp = substr($tnum, 0, 1);
            }

            if (strlen($tnum) < 4) {
                // too short
                return null;
            }
        }

        $formats = array(
            'international' => array(
                array('/\+(?P<zone>\d+) (?P<area>\d+) (?P<num>\d+)\-(?P<internal>\d+)/', 'DIN5008'),
                array('/\+(?P<zone>\d+) (?P<area>\d+) (?P<num>\d+) ?(?P<internal>\d+)?/', 'E.123'),
                array('/\+(?P<zone>\d+) \((?P<area>\d+)\) (?P<num>\d+)$/', 'MSN'),
                array('/\+(?P<zone>\d+) \((?P<area>\d+)\) (?P<num>\d+)\-(?P<internal>\d+)/', 'MSN2'),
                array('/\+(?P<zone>\d+)\-(?P<area>\d+)\-(?P<num>\d+)\-?(?P<internal>\d+)?/', 'RFC3966'),
                array('/\+(?P<zone>\d+) \(0\)(?P<area>\d+) (?P<num>\d+)\-(?P<internal>\d+)/', 'DE'),
                array('/\+(?P<zone>\d+) (?P<area>\d+)\-(?P<num>\d+) ?(?P<internal>\d+)?/', 'USA'),
            ),
            'national' => array(
                array('/^(?P<area>\d+) (?P<num>\d+)\-(?P<internal>\d+)$/', 'DIN5008'),
                array('/^(?P<area>\d+) (?P<num>\d+) ?(?P<internal>\d+)?$/', 'E.123'),
                array('/^(?P<area>\d+)\/(?P<num>\d+)\-(?P<internal>\d+)$/', 'FAKE1'),
                array('/^(?P<area>\d+)\-(?P<num>\d+) ?(?P<internal>\d+)?$/', 'USA'),
            ),
            'internal' => array(
                array('/^(?P<internal>[1-9]{1,6})$/', 'INTERNAL')
            ),
            'unknow' => array(
                array('/^(?P<internal>[1-9]\d+)/', 'UNKNOW')
            ),
        );

        $number = strval(trim($number));

        $currentformat = array();
        $currentformat['parse'] = null;

        foreach ($formats as $key => $value) {
            for ($e = 0; $e < count($value); $e++) {
                $currentformat['parse'] = null;

                if ((preg_match($value[$e][0], $number, $currentformat['parse']))) {
                    $currentformat['raw'] = $number;
                    $currentformat['provenance'] = $key;
                    $currentformat['type'] = $value[$e][1];
                    $currentformat['format'] = $value[$e][0];

                    if (strcasecmp('DE', $value[$e][1]) == 0) {
                        $number = str_replace("(0)", "", $number);
                    }

                    $currentformat['clean'] = str_replace("+", "00", $number);
                    $currentformat['clean'] = preg_replace('[\D]', '', $currentformat['clean']);

                    if ($key == 'international') {
                        $currentformat['intl_clean'] = $currentformat['clean'];
                    }
                    break;
                }
            }

            if ($currentformat['parse'] != null) {
                break;
            }
        }

        /**
         * Wenn nix passt nummer Cleanen
         */
        if (($currentformat['parse'] != null) || (count($currentformat['parse']) == 0)) {
            $currentformat['clean'] = str_replace("+", "00", $number);
            $currentformat['clean'] = preg_replace('[\D]', '', $currentformat['clean']);
        }

        if (!isset($currentformat['intl_clean'])) {
            $tnum = "00" . $countryprefix;

            if ((strcasecmp(substr($currentformat['clean'], 0, 1), "0") == 0) &&
                    (strcasecmp(substr($currentformat['clean'], 0, 2), "00") != 0)) {
                $tnum .= substr($currentformat['clean'], 1);
            } else {
                $tnum .= $currentformat['clean'];
            }
            $currentformat['intl_clean'] = $tnum;
        }
        return $currentformat;
    }

    static function canonize($number)
    {
        $formats = array(
            'international' => array(
                array('/\+(?P<zone>\d+) (?P<area>\d+) (?P<num>\d+)\-(?P<internal>\d+)/', 'DIN5008'),
                array('/\+(?P<zone>\d+) (?P<area>\d+) (?P<num>\d+) ?(?P<internal>\d+)?/', 'E.123'),
                array('/\+(?P<zone>\d+) \((?P<area>\d+)\) (?P<num>\d+)$/', 'MSN'),
                array('/\+(?P<zone>\d+) \((?P<area>\d+)\) (?P<num>\d+)\-(?P<internal>\d+)/', 'MSN2'),
                array('/\+(?P<zone>\d+)\-(?P<area>\d+)\-(?P<num>\d+)\-?(?P<internal>\d+)?/', 'RFC3966'),
                array('/\+(?P<zone>\d+) \(0\)(?P<area>\d+) (?P<num>\d+)\-(?P<internal>\d+)/', 'DE'),
                array('/\+(?P<zone>\d+) (?P<area>\d+)\-(?P<num>\d+) ?(?P<internal>\d+)?/', 'USA'),
            ),
            'national' => array(
                array('/^(?P<area>\d+) (?P<num>\d+)\-(?P<internal>\d+)$/', 'DIN5008'),
                array('/^(?P<area>\d+) (?P<num>\d+) ?(?P<internal>\d+)?$/', 'E.123'),
                array('/^(?P<area>\d+)\/(?P<num>\d+)\-(?P<internal>\d+)$/', 'FAKE1'),
                array('/^(?P<area>\d+)\-(?P<num>\d+) ?(?P<internal>\d+)?$/', 'USA'),
            ),
            'internal' => array(
                array('/^(?P<internal>[1-9]{1,6})$/', 'INTERNAL')
            ),
            'unknow' => array(
                array('/^(?P<internal>[1-9]\d+)/', 'UNKNOW')
            ),
        );

        $number = strval(trim($number));

        $currentformat = array();
        $currentformat['parse'] = null;

        foreach ($formats as $key => $value) {
            for ($e = 0; $e < count($value); $e++) {
                $currentformat['parse'] = null;

                if ((preg_match($value[$e][0], $number, $currentformat['parse']))) {
                    $currentformat['raw'] = $number;
                    $currentformat['provenance'] = $key;
                    $currentformat['type'] = $value[$e][1];
                    $currentformat['format'] = $value[$e][0];
                    $currentformat['clean'] = str_replace("+", "00", $number);
                    $currentformat['clean'] = preg_replace('[\D]', '', $currentformat['clean']);
                    break;
                }
            }

            if ($currentformat['parse'] != null) {
                break;
            }
        }

        if (($currentformat['parse'] != null) || (count($currentformat['parse']) == 0)) {
            $currentformat['clean'] = str_replace("+", "00", $number);
            $currentformat['clean'] = preg_replace('[\D]', '', $currentformat['clean']);
        }

        if (substr($currentformat['clean'], 0, 1) == "0" && substr($currentformat['clean'], 0, 2) != "00") {
            $currentformat['intl_clean'] = cfg('DP_INTL_PREFIX') . substr($currentformat['clean'], 1);
        } else {
            $currentformat['intl_clean'] = $currentformat['clean'];
        }
        return $currentformat['intl_clean'];
    }

    function split_tele_number($cleannum)
    {
        $parts = array(
            'country' => array(
                'found' => false,
                'value' => ""),
            'area' => array(
                'found' => false,
                'value' => ""),
            'num' => array(
                'found' => false,
                'value' => ""),
        );

        $bpos = 0;

        $zoneprefix = "00"; // Standard Deutschland
        $poszprefix = strlen($zoneprefix);

        $tmp = substr($cleannum, $bpos, $poszprefix);

        if (strcasecmp($zoneprefix, $tmp) == 0) {
            $len = 1;
            $tnum = substr($cleannum, ($bpos + $poszprefix), $len);
            $data = $this->getCountryCode("`country_code` LIKE '$tnum%'");

            while ((count($data) != 1)) {
                $len++;

                if ($len > strlen($cleannum)) {
                    break;
                }

                $tnum = substr($cleannum, ($bpos + $poszprefix), $len);
                $data = $this->getCountryCode("`country_code` LIKE '$tnum%'");
            }

            if (count($data) == 1) {
                $parts['country']['found'] = true;
                $parts['country']['value'] = $data;
            }
            $bpos = $bpos + $poszprefix + $len;
        }
        $areaprefix = "0";
        $tmp = substr($cleannum, $bpos, strlen($areaprefix));

        if (strcasecmp($areaprefix, $tmp) == 0) {
            $bpos++;
        }

        if ($bpos > 0) {
            $len = 1;
            $tnum = substr($cleannum, $bpos, $len);
            $data = $this->getAreaCode("`area_code` LIKE '$tnum%'");

            while ((count($data) != 1)) {
                $len++;

                /**
                 * Endlosschleife vermeiden
                 * ( bei Nummer von Usern die keinen sin haben)
                 */
                if ($len > strlen($cleannum)) {
                    break;
                }
                $tnum = substr($cleannum, $bpos, $len);
                $tdata = $this->getAreaCode("`area_code` LIKE '$tnum%'");

                if (count($tdata) == 0) {
                    $len--;
                    break;
                } else {
                    $data = $tdata;
                }
            }

            /**
             * mehr als 3 nummern ist glaubhaft
             */
            if ($len >= 3) {
                $parts['area']['found'] = true;
                $parts['area']['value'] = $data;
            }
            $bpos = $bpos + $len;
        }

        /**
         * num
         */
        $tnum = substr($cleannum, $bpos, strlen($cleannum));
        $parts['num']['found'] = true;
        $parts['num']['value'] = $tnum;
        return $parts;
    }

    function convert_tele_number($num, $format)
    {
        
    }
}
