<?php

include 'AbstractXmlApp.php';

abstract class AbstractXMLPhonebookApp extends AbstractXMLApp
{

    protected $pbID;
    protected $addressID;
    protected $offset;
    protected $search;
    protected $next;
    protected $selection;
    protected $search_request;
    protected $search_done;
    protected static $limit = 20;
    protected $contactNumber;
    protected $backToPhonebooks;
    protected $backToContacts;
    protected $makeCall;
    protected $keypadSearch;
    protected $exit;

    protected function getNextPageURI()
    {
        $offset = $this->offset + AbstractXMLPhonebookApp::$limit;
        $params = array(
            'offset' => $offset,
            'pbid' => $this->pbID,
            'next' => 1
        );
        return $this->appURL($params);
    }

    protected function getNextSearchPageURI($search_request)
    {
        $offset = $this->offset + AbstractXMLPhonebookApp::$limit;
        $params = array(
            'offset' => $offset,
            'pbid' => $this->pbID,
                        'search_request' => $search_request,
            'next' => 1,

        );
        return $this->appURL($params);
    }

    protected function getPhonebookURI($offset = 0)
    {
        $URI = $this->appURL(array('offset' => $offset));
        return $URI;
    }

    protected function getAddressesURI($params = array())
    {
        if (!empty($this->pbID)) {
            $pbid = array('pbid' => $this->pbID);
            $params = array_merge($pbid, $params);
        }
        $URI = $this->appURL($params);
        return $URI;
    }

    protected function getAddressNumberURI()
    {
        $URI = $this->getAddressesURI(array('addressid' => $this->addressID));
        return $URI;
    }

    protected function getSearchScreenURI()
    {
        $URI = $this->getAddressesURI(array('search' => 1));
        return $URI;
    }

    protected function getSearchURI()
    {
        $URI = $this->getAddressesURI(array('search_done' => 1));
        return $URI;
    }

    protected function getSearchResultURI()
    {
        $URI = $this->getAddressesURI();
        return $URI . "&search_result=";
    }

    protected function phoneNumberIcons($name)
    {
        $iconUrl = '/img/16x16/xmlIcons/';
        $host = app()->request->getHostInfo();
        return $host . $iconUrl . $name . '.png';
    }

    protected function showPhoneBooks()
    {
        //load all adressbooks for this user
        $books = $this->mUser->getAddressbooks();
        $this->renderPhoneBooks($books);
    }

    protected function showAddresses()
    {
        // selected phonebook is now known!
        //check permission
        if ($this->mUser->hasPermission($this->pbID, "read")) {
            $book = Addressbook::model()->findByPk($this->pbID);
            if ($book) {
                $addresses = $book->getAddresses($this->mUser->id, AbstractXMLPhonebookApp::$limit, $this->offset, 'name');
                if ($book->type == AddressbookType::personal) {
                    $addressCount = Addresses::model()->countAllByAttributes(array('contact_tid' => $book->id, 'contact_owner' => $this->mUser->id));
                } else {
                    $addressCount = Addresses::model()->countAllByAttributes(array('contact_tid' => $book->id));
                }
                $this->renderPhoneAdresses($book->title, $addresses, $addressCount);
            }
        } else {
            die("not allowed.");
        }
    }

    protected function convertNumberToChars($searchRequest)
    {
        switch ($searchRequest) {
            case '0':
                $searchFor = array('');
                break;
            case '1':
                $searchFor = array('');
                break;
            case '2':
                $searchFor = array('a', 'b', 'c');
                break;
            case '3':
                $searchFor = array('d', 'e', 'f');
                break;
            case '4':
                $searchFor = array('g', 'h', 'i');
                break;
            case '5':
                $searchFor = array('j', 'k', 'l');
                break;
            case '6':
                $searchFor = array('m', 'n', 'o');
                break;
            case '7':
                $searchFor = array('p', 'q', 'r', 's');
                break;
            case '8':
                $searchFor = array('t', 'u', 'v');
                break;
            case '9':
                $searchFor = array('w', 'x', 'y', 'z');
                break;
            case '*':
                $searchFor = array('');
                break;
            case '#':
                $searchFor = array('');
                break;
        }
        return $searchFor;
    }

    protected function processSearchRequestData($incomming, &$searchQuery)
    {
        $unsetKeys = array();
        $newSearchQuery = array();
        foreach ($searchQuery as $key => $value) {
            $unsetKeys[] = $key;
            for ($i = 0; $i < count($incomming); $i++) {
                $newSearchQuery[] = $value . $incomming[$i];
            }
        }
        foreach ($unsetKeys as $key) {
            unset($searchQuery[$key]);
        }
        $searchQuery = $newSearchQuery;
    }

    protected function processKeypadSearch()
    {
        $sort = 'n_family';
        $limit = AbstractXMLPhonebookApp::$limit;
        $offset = $this->offset;
        $book = Addressbook::model()->findByPk($this->pbID);

        $addresses = array();
        $search = array();
        $searchRequest = $this->keypadSearch;
        $searchNextChar = $this->search_done;
        $search_done = null;
        $searchQuery = array('');

        if ($searchRequest != '1' && $searchRequest != '0' && $searchRequest != '*' && $searchRequest != '#') {

            if (isset($searchNextChar)) {
                $search_done = $searchNextChar . '+' . $searchRequest;
                $explode = explode('+', $search_done);
                $explode = array_filter($explode);

                foreach ($explode as $searchRequest) {
                    $requests[] = $this->convertNumberToChars($searchRequest);
                }

                $searchQuery = array_slice($requests, 0, 1);
                $requests = array_slice($requests, 1);


                foreach ($requests as $incomming) {
                    $this->processSearchRequestData($incomming, $searchQuery[0]);
                }

                foreach ($searchQuery[0] as $value) {
                    $result[] = ucfirst($value);
                }
                $searchQuery = $result;
            } else {
                $searchRequestOneChar = $this->convertNumberToChars($searchRequest);
                foreach ($searchRequestOneChar as $value) {
                    $result[] = ucfirst($value);
                }
                $searchQuery = $result;
                $search_done = $searchRequest;
            }
        }


        foreach ($searchQuery as $key => $value) {
            if ($this->mUser->hasPermission($this->pbID, "read")) {
                if ($book->type == AddressbookType::personal) {
                    $search = Addresses::model()->find(array(
                        'n_family' => $value . '*',
                        'contact_tid' => $this->pbID,
                        'contact_owner' => $this->mUser->id
                            ), $sort, $limit, $offset
                    );
                } else {
                    $search = Addresses::model()->find(array(
                        'n_family' => $value,
                        'contact_tid' => $this->pbID,
                            ), $sort, $limit, $offset
                    );
                }

                foreach ($search as $address) {
                    $addresses[$address->id] = $address;
                }
            }
        }

        $searchRequestText = '';
        foreach ($searchQuery as $key => $value) {
            $searchRequestText .= $value . ' ';
        }
        $searchRequestText = substr($searchRequestText, 0, -1);

        $addressesCount = count($addresses);
        $header = $book->title;
        if (!empty($searchRequestText)) {
            $header = $this->getHeaderText($addressesCount, $searchRequestText);
        }
        return $this->renderPhoneAdresses($header, $addresses, $addressesCount, $searchRequestText, $search_done);
    }

    protected function processSearchRequest()
    {
        $sort = 'n_family';
        $limit = AbstractXMLPhonebookApp::$limit + 1;
        $offset = $this->offset;

        $searchFor = array(
            'n_family',
            'n_given',
            'n_middle',
            'org_name',
            'tel_assistent_ic',
            'tel_car_ic',
            'tel_cell_ic',
            'tel_cell_private_ic',
            'tel_home_ic',
            'tel_work_ic'
        );

        $addresses = array();
        $search = array();
        $search_done = null;
        $book = Addressbook::model()->findByPk($this->pbID);

        $searchRequest = $this->search_request . '*';

        foreach ($searchFor as $key => $value) {
            if ($this->mUser->hasPermission($this->pbID, "read")) {

                if ($book->type == AddressbookType::personal) {
                    $search = Addresses::model()->find(array(
                        $value => $searchRequest,
                        'contact_tid' => $this->pbID,
                        'contact_owner' => $this->mUser->id
                            ), $sort, $limit, $offset
                    );
                } else {
                    $search = Addresses::model()->find(array(
                        $value => $searchRequest,
                        'contact_tid' => $this->pbID,
                            ), $sort, $limit, $offset
                    );
                }
                foreach ($search as $address) {
                    $addresses[$address->id] = $address;
                }
            }
        }

        $addressesCount = count($addresses);
        if ($addressesCount == 21) {
            array_pop($addresses);
        }
        $searchRequestText = $this->search_request;
        $header = $this->getHeaderText($addressesCount, $searchRequestText);
        return $this->renderSearchResult($header, $addresses, $addressesCount, $searchRequestText, $search_done);
    }

    public function showAddressDetails()
    {
        $address = Addresses::model()->findByPk($this->addressID);
        $this->renderPhoneAddress($address);
    }

    protected function setAttributes()
    {
        $this->pbID = @$_REQUEST["pbid"];
        $this->next = @$_REQUEST["next"];
        $this->offset = (int) @$_REQUEST["offset"];
        $this->search = @$_REQUEST["search"];
        $this->contactNumber = @$_REQUEST["contactnumber"];
        $this->search_request = @$_REQUEST["search_request"];
        $this->search_done = @$_REQUEST["search_done"];
        $this->keypadSearch = @$_REQUEST["keypadSearch"];
        $this->backToPhonebooks = @$_REQUEST["backToPhonebooks"];
        $this->backToContacts = @$_REQUEST["backToContacts"];
        $this->makeCall = isset($_REQUEST["makeCall"]) ? true : false;
        $this->afterCall = isset($_REQUEST["afterCall"]) ? true : false;
        if ($this->next == false) { //hack for Tiptel "submit"
            $this->addressID = @$_REQUEST["addressid"];
            $this->selection = @$_REQUEST["selection"];
        }
        $this->exit = @$_REQUEST["exit"];
    }

    public function run($controller)
    {
        parent::run($controller);
        if ($this->mUser == null) {
            die("not allowed.");
        }
        $this->setAttributes();

        if ($this->exit) {
            return $this->renderExit();
        }

        if ($this->keypadSearch) {
            return $this->processKeypadSearch();
        }

        if ($this->search_request) {
            return $this->processSearchRequest();
        }

        if ($this->search) {
            return $this->renderSearch();
        }

        if ($this->makeCall) {
            $address = Addresses::model()->findByPk($this->addressID);
            return $this->renderMakeCall($address);
        }

        if ($this->contactNumber) {
            $address = Addresses::model()->findByPk($this->addressID);
            return $this->renderAddressNumber($address);
        }

        if ($this->addressID) {
            if ($this->backToContacts) {
                $this->showAddresses();
            } else {
                $this->showAddressDetails();
            }
            return;
        }
        if ($this->pbID && !$this->backToPhonebooks) {
            return $this->showAddresses();
        }

        $this->showPhoneBooks();
    }

    public function getHeaderText($addressesCount, $searchRequestText)
    {
        $this->setPhonebookLanguage();
        $text = 'XML_PHONEBOOK_FOUND_ENTRIES';
        if ($addressesCount == 1) {
            $text = 'XML_PHONEBOOK_FOUND_ENTRY';
        }
        return __($text, true, 'messages', array("{count}" => $addressesCount, "{result}" => $searchRequestText));
    }

    public function setPhonebookLanguage()
    {
        $Phone = $this->getPhoneModel();
        $SipAccount = $Phone->getSipAccount();
        $User = $SipAccount->getUser();

        $language = cfg("GUI_LANGS");
        if ($User && $User->user_language != "") {
            $language = $User->user_language;
        }
        Yii::app()->setLanguage($language);
    }
}
