<?php

require_once dirname(__FILE__) . '/../../lib/AbstractPhoneModel.php';

class Tiptel extends AbstractPhoneModel
{

    public function __construct($manufactorName = "Tiptel", $phoneModelName = "", $phoneUserAgent = "")
    {
        $this->mManufactorName = $manufactorName;
        $this->mPhoneModelName = $phoneModelName;
        $this->mPhoneUserAgent = $phoneUserAgent;
    }

    public static function getManufactorName()
    {
        return "Tiptel";
    }

    public static function getFunctionPlaceholders()
    {
        return array(
            'no' => 'PHONE_TIPTEL_FUNCTION_NOT_OVERRIDE',
            '0' => 'PHONE_TIPTEL_FUNCTION_EMPTY',
            '5' => 'PHONE_TIPTEL_FUNCTION_DND', // DND
            '6' => 'PHONE_TIPTEL_FUNCTION_REDIAL', // Redial
            '12' => 'PHONE_TIPTEL_FUNCTION_VOICEMAIL', // Voicemail
            '13' => 'PHONE_TIPTEL_FUNCTION_SPEEDDIAL', // SpeedDial
            '14' => 'PHONE_TIPTEL_FUNCTION_INTERCOM', // Intercom
            '15' => 'PHONE_TIPTEL_FUNCTION_LINE', // Line (for line key only)
            '16' => 'PHONE_TIPTEL_FUNCTION_BUSY_LAMP_FIELD', // BLF
            '25' => 'PHONE_TIPTEL_FUNCTION_RECORD', // Record
            'X01' => 'PHONE_TIPTEL_FUNCTION_FORWARD', // Call Forward
            'X02' => 'PHONE_TIPTEL_FUNCTION_NIGHT_CIRCUT', // Night Circuit
            'X03' => 'PHONE_TIPTEL_FUNCTION_QUEUE_LOGIN', // Queue Login/Logout
            'X04' => 'PHONE_TIPTEL_FUNCTION_SPEEDDIAL_PHONALISA', // SpeedDial
            'X06' => 'PHONE_TIPTEL_FUNCTION_CALL_PICKUP', // Direct Pickup
            'X09' => 'PHONE_TIPTEL_FUNCTION_LISTENING', // Group Listening
            'X10' => 'PHONE_TIPTEL_FUNCTION_ALL_QUEUES_LOGOUT', // Logout from all Queues
            'X11' => 'PHONE_TIPTEL_FUNCTION_HOT_DESKING', // Hot Desking
            'X12' => 'PHONE_TIPTEL_FUNCTION_ALL_QUEUES_LOGIN', // Login to all Queues
            'X13' => 'PHONE_TIPTEL_FUNCTION_CALLGROUP_LOGIN', // Call Group Login/Logout
        );
    }

    public static function getFunctionTiptel31xxPlaceholders($level = '')
    {
        return array(
            'no' => 'PHONE_TIPTEL_FUNCTION_NOT_OVERRIDE',
            '0' => 'PHONE_TIPTEL_FUNCTION_EMPTY',
            '6' => 'PHONE_TIPTEL_FUNCTION_REDIAL', // Redial
            '13' => 'PHONE_TIPTEL_FUNCTION_SPEEDDIAL', // SpeedDial
            '15' => 'PHONE_TIPTEL_FUNCTION_LINE', // Line (for line key only)
            '16' => 'PHONE_TIPTEL_FUNCTION_BUSY_LAMP_FIELD', // BLF
            '25' => 'PHONE_TIPTEL_FUNCTION_RECORD', // Record
            'X01' => 'PHONE_TIPTEL_FUNCTION_FORWARD', // Call Forward
            'X02' => 'PHONE_TIPTEL_FUNCTION_NIGHT_CIRCUT', // Night Circuit
            'X03' => 'PHONE_TIPTEL_FUNCTION_QUEUE_LOGIN', // Queue Login/Logout
            'X04' => 'PHONE_TIPTEL_FUNCTION_SPEEDDIAL_PHONALISA', // SpeedDial
            'X05' => 'PHONE_TIPTEL_FUNCTION_VOICEMAIL', // Voicemail
            'X06' => 'PHONE_TIPTEL_FUNCTION_CALL_PICKUP', // Direct Pickup
            'X07' => 'PHONE_TIPTEL_FUNCTION_INTERCOM', // Intercom
            'X08' => 'PHONE_TIPTEL_FUNCTION_DND', // DND
            'X09' => 'PHONE_TIPTEL_FUNCTION_LISTENING', // Group Listening
            'X10' => 'PHONE_TIPTEL_FUNCTION_ALL_QUEUES_LOGOUT', // Logout from all Queues
            'X11' => 'PHONE_TIPTEL_FUNCTION_HOT_DESKING', // Hot Desking
            'X12' => 'PHONE_TIPTEL_FUNCTION_ALL_QUEUES_LOGIN', // Login to all Queues
            'X13' => 'PHONE_TIPTEL_FUNCTION_CALLGROUP_LOGIN', // Call Group Login/Logout
        );
    }

    public function validateFirmwareFileForT31XX($filename, $fileTmpPath, &$errorText)
    {
        $filename = substr($filename, 0, strlen($filename) - 4); // remove .rom
        $filename = substr($filename, 6, strlen($filename) - 6); // remove T31XX-

        $errorText = __("FIRMWARE_VALIDATION_ERROR_WRONG_FILE_IS_NOT_VALID");
        $parts = explode(".", $filename);

        if (count($parts) != 3) {
            return false;
        }

        $tmp = explode('.', $filename);
        $v0 = str_pad((int) @$tmp[0], 2, '0', STR_PAD_LEFT);
        $v1 = str_pad((int) @$tmp[1], 2, '0', STR_PAD_LEFT);
        $v2 = str_pad((int) @$tmp[2], 2, '0', STR_PAD_LEFT);
        return $v0 . '.' . $v1 . '.' . $v2;
    }

    public function validateFirmwareFile($filename, $fileTmpPath, &$errorText)
    {
        // Filename is like: 7.71.0.125.rom
        // OR: T31XX-2.0.101.rom

        if ($filename == "") {
            $errorText = __("FIRMWARE_VALIDATION_ERROR_FILE_NOT_SET");
            return false;
        }

        $errorText = __("FIRMWARE_VALIDATION_ERROR_WRONG_FILE_IS_NOT_VALID");
        // check filename
        if (!$this->endsWith($filename, ".rom")) {
            return false;
        }

        if (substr($filename, 0, 5) == "T31XX" ||
                substr($filename, 0, 5) == "T3110" ||
                substr($filename, 0, 5) == "T3120" ||
                substr($filename, 0, 5) == "T3130") {
            return $this->validateFirmwareFileForT31XX($filename, $fileTmpPath, $errorText);
        }

        $filename = substr($filename, 0, strlen($filename) - 4);
        $parts = explode(".", $filename);

        if (count($parts) != 4) {
            return false;
        }

        $ok = false;
        $versionMatchesForPhone = false;

        if ($parts[0] == "9") {
            if ($this->mPhoneModelName == "yealink-sip-t20p" || $this->mPhoneModelName == "tiptel-ip280") {
                $versionMatchesForPhone = true;
            }
        } else if ($parts[0] == "7") {
            if ($this->mPhoneModelName == "yealink-sip-t22p" || $this->mPhoneModelName == "tiptel-ip282") {
                $versionMatchesForPhone = true;
            }
        } else if ($parts[0] == "6") {
            if ($this->mPhoneModelName == "yealink-sip-t26p" || $this->mPhoneModelName == "tiptel-ip284") {
                $versionMatchesForPhone = true;
            }
        } else if ($parts[0] == "2") {
            if ($this->mPhoneModelName == "yealink-sip-t28p" || $this->mPhoneModelName == "tiptel-ip286") {
                $versionMatchesForPhone = true;
            }
        }

        if (!$versionMatchesForPhone) {
            $errorText = __("FIRMWARE_VALIDATION_ERROR_WRONG_FILE_IS_NOT_A_FIRMWARE_FOR") . ": " . $this->mPhoneModelNameHuman;
            return false;
        }

        $vParts = $parts;
        $vPartsNormal = array();
        $vPartsNormal[] = str_pad($vParts[0], 2, '0', STR_PAD_LEFT);
        $vPartsNormal[] = str_pad($vParts[1], 2, '0', STR_PAD_LEFT);
        $vPartsNormal[] = str_pad($vParts[2], 2, '0', STR_PAD_LEFT);
        $vPartsNormal[] = str_pad($vParts[3], 3, '0', STR_PAD_LEFT);
        $firmwareVersion = implode(".", $vPartsNormal);

        return $firmwareVersion;
    }

    public static function getFunctions($translated = true, $phone = '', $level = '')
    {
        $placeholders = self::getFunctionPlaceholders();
        if (substr(strToLower($phone), 0, 10) == 'tiptel-t31') {
            $placeholders = self::getFunctionTiptel31xxPlaceholders($level);
        }

        if ($translated) {
            $functions = array();
            foreach ($placeholders as $key => $value) {
                $functions[$key] = __($value);
            }
            return $functions;
        } else {
            return $placeholders;
        }
    }

    public function getAvailableKeys($level)
    {
        $phones = $this->getSupportedPhoneModels();
        if (!array_key_exists($this->mPhoneModelName, $phones)) {
            return array();
        }

        $phone = $phones[$this->mPhoneModelName];
        $ret = array();

        if ($level == "" || $level == "memory") {
            for ($i = 1; $i <= $phone->getKeys(); $i++) {
                $button = new PhoneKey();
                $button->name = 'memory' . $i;
                $button->phone = $this->mPhoneModelName;
                $button->function = '';
                $button->level = 'memory';
                $button->key_idx = $i;
                $button->availableFunctions = $this->getFunctions(true, $button->phone, $button->level);
                $ret[$button->name] = $button;
            }
        }

        if ($level == "" || $level == "line") {
            for ($i = 1; $i <= $phone->getLineKeys(); $i++) {
                $keyCount = $this->getKeys();
                if ($keyCount < 10) {
                    $keyCount = 10;
                }
                $linKeySum = $keyCount + $i;
                $button = new PhoneKey();
                $button->name = 'memory' . $linKeySum;
                $button->phone = $this->mPhoneModelName;
                $button->function = '';
                $button->key_idx = $i;
                $button->level = 'line';
                $button->availableFunctions = $this->getFunctions(true, $button->phone, $button->level);

                $ret[$button->name] = $button;
            }
        }

        $extKeys = $phone->getExtKeys();
        $extModules = $phone->getExtModules();
        for ($i = 0; $i <= $extModules - 1; $i++) {
            if ($level == "" || $level == 'ext' . $i) {
                $k = 0;
                if (!startsWith($this->mPhoneUserAgent, 't31')) {
                    $k = 1;
                }
                for ($j = 1; $j <= $extKeys; $j++) {
                    $button = new PhoneKey();
                    $button->phone = $this->mPhoneModelName;
                    $button->function = '';
                    $button->level = 'ext' . $i;
                    $button->key_idx = $this->getExtensionKeyName($i, ($j - $k));
                    $button->name = $this->getExtensionKeyName($i, $j);
                    $button->availableFunctions = $this->getFunctions(true, $button->phone, $button->level);
                    $ret[$button->name] = $button;
                }
            }
        }
        return $ret;
    }

    protected function getExtensionKeyName($i, $j)
    {
        $keyName = "ext" . $i . '.' . $j;
        if (!startsWith($this->mPhoneUserAgent, 't31')) {
            $i++;
            $keyName = "Key$i.$j";
        }
        return $keyName;
    }

    public function getAvailableKeyLevels()
    {
        $phones = $this->getSupportedPhoneModels();
        if (!array_key_exists($this->mPhoneModelName, $phones)) {
            return array();
        }
        $phone = $phones[$this->mPhoneModelName];

        $keyLevels = array();

        if ($phone->getLineKeys() != 0) {
            $lineKeyLevel = array();
            $lineKeyLevel["level"] = "line";
            $lineKeyLevel["name"] = "TIPTEL_KEYLEVEL_LINE_KEYS_NAME";
            $lineKeyLevel["descr"] = "TIPTEL_KEYLEVEL_LINE_KEYS_DESCR";
            $keyLevels[] = $lineKeyLevel;
        }

        if ($phone->getKeys() != 0) {
            $memoryKeyLevel = array();
            $memoryKeyLevel["level"] = "memory";
            $memoryKeyLevel["name"] = "TIPTEL_KEYLEVEL_MEMORY_KEYS_NAME";
            $memoryKeyLevel["descr"] = "TIPTEL_KEYLEVEL_MEMORY_KEYS_DESCR";
            $keyLevels[] = $memoryKeyLevel;
        }

        $extModules = $phone->getExtModules();
        if ($phone->getExtKeys() != 0) {
            for ($i = 0; $i <= $extModules - 1; $i++) {
                $ExtKeyLevel = array();
                $ExtKeyLevel["level"] = "ext" . $i;
                $ExtKeyLevel["name"] = "TIPTEL_KEYLEVEL_EXT" . $i . "_NAME";
                $ExtKeyLevel["descr"] = "TIPTEL_KEYLEVEL_EXT" . $i . "_DESCR";
                $keyLevels[] = $ExtKeyLevel;
            }
        }
        return $keyLevels;
    }

    public static function getSupportedPhoneModels()
    {
        $models = array();
        $tmp = new Tiptel(Tiptel::getManufactorName(), "tiptel-ip28xs", "28xs");
        $tmp->setPhoneModelNameHumanReadable("tiptel IP 28xs");
        $tmp->setKeys(0);
        $tmp->setLineKeys(2);
        $models[$tmp->getPhoneModelName()] = $tmp;

        /* $models[] */
        $tmp = new Tiptel(Tiptel::getManufactorName(), "tiptel-ip280", "280");
        $tmp->setPhoneModelNameHumanReadable("tiptel IP 280");
        $tmp->setKeys(0);
        $tmp->setLineKeys(2);
        $models[$tmp->getPhoneModelName()] = $tmp;

        /* $models[] */
        $tmp = new Tiptel(Tiptel::getManufactorName(), "tiptel-ip282", "282");
        $tmp->setPhoneModelNameHumanReadable("tiptel IP 282");
        $tmp->setKeys(0);
        $tmp->setLineKeys(3);
        $models[$tmp->getPhoneModelName()] = $tmp;


        $tmp = new Tiptel(Tiptel::getManufactorName(), "tiptel-ip284", "284");
        $tmp->setPhoneModelNameHumanReadable("tiptel IP 284");
        $tmp->setKeys(10);
        $tmp->setLineKeys(3);
        $tmp->setExtKeys(38);
        $tmp->setExtModules(3);
        $models[$tmp->getPhoneModelName()] = $tmp;

        /* $models[] */
        $tmp = new Tiptel(Tiptel::getManufactorName(), "tiptel-ip286", "286");
        $tmp->setPhoneModelNameHumanReadable("tiptel IP 286");
        $tmp->setKeys(10);
        $tmp->setLineKeys(6);
        $tmp->setExtKeys(38);
        $tmp->setExtModules(3);
        $models[$tmp->getPhoneModelName()] = $tmp;

        /* $models[] */
        $tmp = new Tiptel(Tiptel::getManufactorName(), "tiptel-t3110", "t3110");
        $tmp->setPhoneModelNameHumanReadable("tiptel 3110");
        $tmp->setKeys(12);
        $tmp->setLineKeys(2);
        $tmp->setExtKeys(27);
        $tmp->setExtModules(3);
        $models[$tmp->getPhoneModelName()] = $tmp;

        $tmp = new Tiptel(Tiptel::getManufactorName(), "tiptel-t3120", "t3120");
        $tmp->setPhoneModelNameHumanReadable("tiptel 3120");
        $tmp->setKeys(12);
        $tmp->setLineKeys(6);
        $tmp->setExtKeys(27);
        $tmp->setExtModules(3);
        $models[$tmp->getPhoneModelName()] = $tmp;

        $tmp = new Tiptel(Tiptel::getManufactorName(), "tiptel-t3130", "t3130");
        $tmp->setPhoneModelNameHumanReadable("tiptel 3130");
        $tmp->setKeys(11);
        $tmp->setLineKeys(6);
        $tmp->setExtKeys(27);
        $tmp->setExtModules(3);
        $models[$tmp->getPhoneModelName()] = $tmp;

        $tmp = new Tiptel(Tiptel::getManufactorName(), "yealink-sip-t22p", "sip-t22p");
        $tmp->setPhoneModelNameHumanReadable("Yealink SIP-T22P");
        $tmp->setKeys(0);
        $tmp->setLineKeys(3);
        $models[$tmp->getPhoneModelName()] = $tmp;

        /* $models[] */
        $tmp = new Tiptel(Tiptel::getManufactorName(), "yealink-sip-t26p", "sip-t26p");
        $tmp->setPhoneModelNameHumanReadable("Yealink SIP-T26P");
        $tmp->setKeys(10);
        $tmp->setLineKeys(3);
        $tmp->setExtKeys(38);
        $tmp->setExtModules(3);
        $models[$tmp->getPhoneModelName()] = $tmp;

        /* $models[] */
        $tmp = new Tiptel(Tiptel::getManufactorName(), "yealink-sip-t28p", "sip-t28p");
        $tmp->setPhoneModelNameHumanReadable("Yealink SIP-T28P");
        $tmp->setKeys(10);
        $tmp->setLineKeys(6);
        $tmp->setExtKeys(38);
        $tmp->setExtModules(3);
        $models[$tmp->getPhoneModelName()] = $tmp;

        /* $models[] */
        $tmp = new Tiptel(Tiptel::getManufactorName(), "yealink-vp-2009", "VP-2009");
        $tmp->setPhoneModelNameHumanReadable("Yealink VP-2009");
        $tmp->setKeys(20);
        $tmp->setLineKeys(0);
        $models[$tmp->getPhoneModelName()] = $tmp;

        return $models;
    }

    public function phoneDoesSupportURLDial($phone)
    {
        $result = false;
        $explodedFirmware = explode('.', $phone->firmware);
        if ($phone->getManufactor() === $this->getManufactorName() && (int) $explodedFirmware[1] > 70) {
            $result = true;
        }
        return $result;
    }

    public function getCallServiceURL($to, $id, $clip)
    {
        $protocol = cfg('PROV_PROTOCOL');
        $host = cfg('PROV_HOST');
        $sipAccount = SipAccounts::model()->findByAttributes(array('user_id' => $id, 'state' => 'online'));
        $userPhoneIP = $sipAccount->current_ip;
        $userPhoneNumber = $sipAccount->authname;
        if ($clip != '') {
            $userPhoneNumber = $clip;
        }
        $url = $protocol . "admin:admin@$userPhoneIP/servlet?number=$to&outgoing_uri=$userPhoneNumber@$host";
        return $url;
    }
}
