<?php

/** SQL
 *
 * CREATE  TABLE "main"."groups" (
 *  "id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL  UNIQUE ,
 *  "type" VARCHAR(20) NOT NULL ,
 *  "name" VARCHAR(40) NOT NULL ,
 * "title" VARCHAR(40) NOT NULL ,
 * "description" VARCHAR(255)
 * )
 */

/**
 * This is the model class for table "groups".
 *
 * The followings are the available columns in table 'groups':
 * @property integer $id
 * @property string $type
 * @property string $name
 * @property string $title
 * @property string $description
 */
class CalendarPermission
{

    const read = 0;
    const write = 1;
    const sync = 2;

}

class Groups extends PhonalisaRecord
{

    const DEFAULT_MAX_RING_TIME = 100;
    const GROUP_TYPE_ALL_USERS = 'allUsers';

    public $id;
    public $parent;
    public $position;
    public $type;
    public $name;
    public $title;
    public $description;
    public $permissions;
    public $playlistId;
    public $extension;
    public $childNumber;
    public $keyProfile;
    public $provisioningProfile;
    public $inboundBlacklistId;
    public $outboundBlacklistId;
    public $inboundWhitelistId;
    public $outboundWhitelistId;
    public $nestedIndex;
    public $nestedName;
    public $faxSendAllowed = User::FAX_SEND_INHERIT_FROM_GROUP;
    public $fax_header_text;
    public $fax_header_number;
    public $droptarget;
    public $target_type_on_timeout;
    public $target_on_timeout;
    public $target_on_timeout_meta;
    public $target_type_on_busy;
    public $target_on_busy;
    public $target_on_busy_meta;
    public $target_type_on_nightcircut;
    public $target_on_nightcircut;
    public $target_on_nightcircut_meta;
    public $accountingEnabled;
    public $night_circut;
    public $scriptExtensionUser;
    public $scriptExtensionGroup;
    public $speedDialList;
    public $maxRingTime = Groups::DEFAULT_MAX_RING_TIME;

    public static function myAttributes()
    {
        return array(
            'id' => 'id',
            'parent' => 'parent',
            'position' => 'position',
            'type' => 'type',
            'name' => 'name',
            'title' => 'title',
            'description' => 'description',
            'permissions' => 'permissions',
            'playlistId' => 'playlistId',
            'extension' => 'extension',
            'childNumber' => 'childNumber',
            'provisioningProfile' => 'provisioningProfile',
            'keyProfile' => 'keyProfile',
            'inboundBlacklistId' => 'inboundBlacklistId',
            'outboundBlacklistId' => 'outboundBlacklistId',
            'inboundWhitelistId' => 'inboundWhitelistId',
            'outboundWhitelistId' => 'outboundWhitelistId',
            'nestedIndex' => 'nestedIndex',
            'nestedName' => 'nestedName',
            'faxSendAllowed' => 'faxSendAllowed',
            "fax_header_text" => "fax_header_text",
            "fax_header_number" => "fax_header_number",
            "droptarget" => "droptarget",
            "target_type_on_timeout" => "target_type_on_timeout",
            "target_on_timeout" => "target_on_timeout",
            "target_on_timeout_meta" => "target_type_on_timeout_meta",
            "target_type_on_busy" => "target_type_on_busy",
            "target_on_busy" => "target_on_busy",
            "target_on_busy_meta" => "target_on_busy_meta",
            "target_type_on_nightcircut" => "target_type_on_nightcircut",
            "target_on_nightcircut" => "target_on_nightcircut",
            "target_on_nightcircut_meta" => "target_type_on_nightcircut_meta",
            "accountingEnabled" => "accountingEnabled",
            'night_circut' => 'night_circut',
            "scriptExtensionUser" => "scriptExtensionUser",
            "scriptExtensionGroup" => "scriptExtensionGroup",
            "speedDialList" => "speedDialList",
            'maxRingTime' => 'maxRingTime'
        );
    }

    /**
     * Returns the static model of the specified AR class.
     * @param string $className active record class name.
     * @return Groups the static model class
     */
    public static function model($className = __CLASS__)
    {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName()
    {
        return 'groups';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules()
    {
        // NOTE: you should only define rules for those attributes that
        // will receive user inputs.
        return array(
            array('name, maxRingTime', 'required'),
            array('night_circut', 'boolean'),
            array('name', 'isUnique'),
            array('extension, fax_header_number, maxRingTime, faxSendAllowed', 'numerical', 'integerOnly' => true),
            array('extension', 'length', 'min' => 2, 'max' => 10),
            array('extension', 'ext.PhonalisaValidators.uniqueExtension', 'on' => 'create'),
            array('extension', 'ext.PhonalisaValidators.uniqueExtension', 'on' => 'update'),
            array(
                'extension',
                'match',
                'pattern' => '/^[1-9]/',
                'message' => __('USER_MODEL_SHOULD_NOT_START_WITH_ZERO_ERROR_MESSAGE')
            ),
            array('type', 'length', 'max' => 20),
            array('name, title', 'length', 'max' => 40),
            array('maxRingTime', 'length', 'max' => 3),
            array(
                'description,'
                . 'keyProfile,'
                . 'provisioningProfile, '
                . 'inboundBlacklistId, '
                . 'outboundBlacklistId, '
                . 'inboundWhitelistId, '
                . 'outboundWhitelistId, '
                . 'playlistId, '
                . 'permissions, '
                . 'id, '
                . 'title, '
                . 'fax_header_text, '
                . 'speedDialList',
                'length',
                'max' => 255
            ),
            // The following rule is used by search().
            // Please remove those attributes that should not be searched.
            array('id, parent, position, type, name, description, childNumber', 'safe', 'on' => 'search'),
            array(
                'accountingEnabled, '
                . 'parent, '
                . 'nestedIndex, '
                . 'droptarget,'
                . 'target_type_on_timeout,'
                . 'target_on_timeout,'
                . 'target_on_timeout_meta,'
                . 'target_type_on_busy,'
                . 'target_on_busy,'
                . 'target_on_busy_meta,'
                . 'target_type_on_nightcircut,'
                . 'target_on_nightcircut,'
                . 'target_on_nightcircut_meta,'
                . 'scriptExtensionUser,'
                . 'scriptExtensionGroup,'
                . 'maxRingTime',
                'safe'
            ),
        );
    }

    public function isUnique($attribute, $params)
    {
        $model = Groups::model()->findByAttributes(array($attribute => $this->$attribute));
        if (!$model) {
            return true;
        }
        if ($model->id == $this->id) {
            return true;
        }
        $this->addError($attribute, $this->getAttributeLabel($attribute) . __('IS_UNIQUE_ERROR_MESSAGE'));
        return false;
    }

    /**
     * @return array relational rules.
     */
    public function relations()
    {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array(
            'permissions' => array(self::HAS_MANY, 'Permissions', 'groupId'),
            'users' => array(self::MANY_MANY, 'User', 'usersToGroups(groupId, userId)')
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels()
    {
        return array(
            'id' => __('USERGROUPS_MODEL_ID'),
            'parent' => __('USERGROUPS_MODEL_PARENT'),
            'position' => __('USERGROUPS_MODEL_POSITION'),
            'type' => __('USERGROUPS_MODEL_TYPE'),
            'name' => __('USERGROUPS_MODEL_NAME'),
            'title' => __('USERGROUPS_MODEL_TITLE'),
            'description' => __('USERGROUPS_MODEL_DESCRIPTION'),
            'permissions' => __('USERGROUPS_MODEL_PERMISSIONS'),
            'playlistId' => __('USERGROUPS_MODEL_PLAYLIST_ID'),
            'childNumber' => 'childNumber',
            'inboundBlacklistId' => __('USERGROUP_MODEL_INBOUND_BLACKLIST'),
            'outboundBlacklistId' => __('USERGROUP_MODEL_OUTBOUND_BLACKLIST'),
            'inboundWhitelistId' => __('USERGROUP_MODEL_INBOUND_WHITELIST'),
            'outboundWhitelistId' => __('USERGROUP_MODEL_OUTBOUND_WHITELIST'),
            'keyProfile' => __('USERGROUP_MODEL_KEY_PROFILE'),
            'provisioningProfile' => __('USERGROUP_MODEL_PROVISIONING_PROFILE'),
            'faxSendAllowed' => __('USERS_MODEL_FAX_SENDING_ALLOWED'),
            'fax_header_text' => __('GROUPS_MODEL_FAX_HEADER_TEXT'),
            'fax_header_number' => __('GROUPS_MODEL_FAX_HEADER_NUMBER'),
            'droptarget' => __("GROUPS_MODEL_DROP_TARGET"),
            'target_type_on_timeout' => __("USERGROUPS_MODEL_TYPE_TARGET_ON_TIMEOUT"),
            'target_on_timeout' => __("USERGROUPS_MODEL_TARGET_ON_TIMEOUT"),
            'target_on_timeout_meta' => __("USERGROUPS_MODEL_TARGET_ON_TIMEOUT_META"),
            'target_type_on_busy' => __("USERGROUPS_MODEL_TYPE_TARGET_ON_BUSY"),
            'target_on_busy' => __("USERGROUPS_MODEL_TARGET_ON_BUSY"),
            'target_on_busy_meta' => __("USERGROUPS_MODEL_TARGET_ON_BUSY_META"),
            'target_on_nightcircut' => __("USERGROUPS_MODEL_TARGET_ON_NIGHTCIRCUT"),
            'target_type_on_nightcircut' => __("USERGROUPS_MODEL_TARGET_TYPE_ON_NIGHTCIRCUT"),
            'target_on_nightcircut_meta' => __("USERGROUPS_MODEL_TARGET_ON_NIGHTCIRCUT_META"),
            'accountingEnabled' => __("USERGROUPS_MODEL_ACCOUNTING_ENABLED"),
            'extension' => __('USERGROUPS_MODEL_EXTENSION'),
            'night_circut' => __('USERGROUPS_MODEL_NIGHT_CIRCUT'),
            "scriptExtensionUser" => __("USER_MODEL_SCRIPT_EXTENSION_USER"),
            "scriptExtensionGroup" => __("USER_MODEL_SCRIPT_EXTENSION_GROUP"),
            "speedDialList" => __('GROUPS_MODEL_SPEED_DIAL_LIST'),
            "maxRingTime" => __('GROUPS_MODEL_MAX_RING_TIME'),
        );
    }

    /**
     * Retrieves a list of models based on the current search/filter conditions.
     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
     */
    public function newRecordSearch()
    {
        $modelsArray = $this->find(array(), 'nestedIndex DESC'); // FIXME limit/offset ???
        $newmodel = new Groups;

        $newmodel->nestedName = __('GROUPS_MODEL_CURRENT_GROUP');
        $newmodel->name = __('GROUPS_MODEL_CURRENT_GROUP');
        $newmodel->id = 'new';
        $modelsArray[] = $newmodel;
        return new CArrayDataProvider(array_reverse($modelsArray), array('pagination' => false));
    }

    public function getDataProvider($criteria, $order = 'id', $enableSorting = true)
    {
        $filter = $this->getFilter($criteria, $order);
        if (!$enableSorting) {
            $arrayDataProvider = new CArrayDataProvider(
                    $this->find(
                            array(), 'nestedIndex'
                    ), array('pagination' => false)
            );

            // fix string sorted integers 
            $this->sortDataByNestedIndex($arrayDataProvider);
            return $arrayDataProvider;
        }
        $phonalisaDataProvider = new CPhonalisaDataProvider($this, $filter);
        return $phonalisaDataProvider;
    }

    private function sortDataByNestedIndex(&$arrayDataProvider)
    {
        $data = array();
        foreach ($arrayDataProvider->data as $value) {
            $data[(int) $value->nestedIndex] = $value;
        }
        ksort($data);
        $arrayDataProvider->data = $data;
    }

    public function search($order = 'name', $enableSorting = true)
    {
        $criteria = new CDbCriteria();
        $criteria->order = $order;
        return $this->getDataProvider($criteria, $order, $enableSorting);
    }

    public function renderPermissions(PhonalisaRecord $data, $row, $column)
    {
        if ($column->id == 'csvImport') {
            if ($data->type == AddressbookType::intern) {
                return CHtml::checkBox('internCSVImportPermission', false, array('disabled' => 'disabled'));
            }
        }
        $htmlOptions['id'] = 'Permissions_' . $data->id . '_' . $column->id . '_cb';
        $htmlOptions['class'] = $column->id;
        $htmlOptions['data-custom-contexthelp-key'] = "GROUP_" . strtoupper($column->id) . "_CONTEXT_HELP";

        $html = CHtml::hiddenField('Permissions[' . $data->id . '][' . $column->id . ']', '0');
        $html .= CHtml::checkBox('Permissions[' . $data->id . '][' . $column->id . ']', false, $htmlOptions);
        return $html;
    }

    public function renderGroupNames($data, $row)
    {
        return $data->name;
    }

    public function afterSave()
    {
        if ($this->isNewRecord) {
            $this->updateNestedIndex();
        }
        foreach ($this->getUsers() as $user) {
            ErgophoneHelper::createErgophoneConfigFilesForExtension($user->extension);
        }
        return parent::afterSave();
    }

    public function beforeSave()
    {
        // Update
        $oldModel = $this->findByPk($this->id);
        if ($oldModel != null && !$this->isNewRecord) {
            if (($oldModel->parent != $this->parent) || ($oldModel->name != $this->name)) {
                $this->updateNestedIndex();
            }
        }
        if ($this->type == '') {
            $this->type = 'user';
        }

        if ($this->maxRingTime == '') {
            $this->maxRingTime = Groups::DEFAULT_MAX_RING_TIME;
        }
        return parent::beforeSave();
    }

    public function beforeDelete()
    {
        // move childgroups to parent
        foreach ($this->getChildGroups() as $group) {
            $group->parent = $this->parent;
            $group->save();
        }

        // move user to parent group
        foreach ($this->getUsers() as $user) {
            $user->group = $this->parent;
            $user->save();
        }
        $permissions = new Permissions();
        $permissions->deletePermissionsFile();
        return parent::beforeDelete();
    }

    public function afterDelete()
    {
        $permissions = Permissions::model()->findAllByAttributes(array('groupId' => $this->id));
        foreach ($permissions as $permission) {
            $permission->delete();
        }
        $permissions = Permissions::model()->findAllByAttributes(array('itemId' => $this->id));
        foreach ($permissions as $permission) {
            $permission->delete();
        }
        $webGuiPermissions = WebGuiPermissions::model()->findByAttributes(array('groupId' => $this->id));
        if (isset($webGuiPermissions)) {
            $webGuiPermissions->delete();
        }
        $this->updateNestedIndex();
        return parent::afterDelete();
    }

    public function getWebGuiPermissions()
    {
        $webGuiPermissions = WebGuiPermissions::model()->findByAttributes(array('groupId' => $this->id));
        if (isset($webGuiPermissions)) {
            $permissions = json_decode($webGuiPermissions->permissions);
            return $permissions;
        }
    }

    public function findByAttributes($attributes, $limit = 100, $offset = 0 /* ,$condition='',$params=array() */)
    {
        $model = parent::findByAttributes($attributes, $limit = 100, $offset = 0 /* ,$condition='',$params=array() */);
        return $model;
    }

    public function availableGroupTypes()
    {

        $availableGroupTypes = array();

        $availableGroupTypes["groups"]["checkBoxColumns"]["sudo"] = array('header' => 'USERGROUPS_MODEL_SUDO_PERMISSIONS');
        $availableGroupTypes["groups"]["checkBoxColumns"]["monitor"] = array('header' => 'USERGROUPS_MODEL_MONITOR_PERMISSIONS');
        $availableGroupTypes["groups"]["checkBoxColumns"]["pickup"] = array('header' => 'USERGROUP_MODEL_PICKUP_PERMISSION');

        if (PhonalisaLicenseManager::analyticsDailyReportEnabled()) {
            $availableGroupTypes["groups"]["checkBoxColumns"]["statisticGroup"] = array('header' => 'USERGROUP_MODEL_STATISTIC_PERMISSION');
        }
        $availableGroupTypes["groups"]["checkBoxColumns"]["intercom"] = array('header' => 'USERGROUP_MODEL_INTERCOM_PERMISSION');
        $availableGroupTypes["groups"]["checkBoxColumns"]["eavesdrop"] = array('header' => 'USERGROUP_MODEL_EAVESDROP_PERMISSION');

        $availableGroupTypes["groups"]["titleColumn"]["title"] = "nestedName";
        $availableGroupTypes["groups"]["titleColumn"]["label"] = "USERGROUPS_MODEL_NAME";
        $availableGroupTypes["groups"]["titleColumn"]["value"] = '$data->name';

        $availableGroupTypes["addressbooks"]["checkBoxColumns"]["read"] = array('header' => 'USERGROUP_MODEL_READ_PERMISSION');
        $availableGroupTypes["addressbooks"]["checkBoxColumns"]["write"] = array('header' => 'USERGROUP_MODEL_WRITE_PERMISSION');
//        $availableGroupTypes["addressbooks"]["checkBoxColumns"]["sync"] = array('header' => 'USERGROUP_MODEL_SYNC_PERMISSION');
        $availableGroupTypes["addressbooks"]["checkBoxColumns"]["csvImport"] = array('header' => 'USERGROUP_MODEL_CSSV_IMPORT_PERMISSION');

        $availableGroupTypes["addressbooks"]["titleColumn"]["title"] = "title";
        $availableGroupTypes["addressbooks"]["titleColumn"]["label"] = "USERGROUPS_MODEL_ADDRESSBOOKS";
        $availableGroupTypes["addressbooks"]["titleColumn"]["value"] = '$data->title';
        $availableGroupTypes["addressbooks"]["modelName"] = "Addresses";

        $availableGroupTypes["calendar"]["checkBoxColumns"]["read_calendar"] = array('header' => 'USERGROUP_MODEL_READ__CALENDAR_PERMISSION');
        $availableGroupTypes["calendar"]["checkBoxColumns"]["write_calendar"] = array('header' => 'USERGROUP_MODEL_WRITE_CALENDAR_PERMISSION');
//        $availableGroupTypes["calendar"]["checkBoxColumns"]["sync_calendar"] = array('header' => 'USERGROUP_MODEL_SYNC_CALENDAR_PERMISSION');
        $availableGroupTypes["calendar"]["titleColumn"]["title"] = "title";
        $availableGroupTypes["calendar"]["titleColumn"]["label"] = "USERGROUPS_MODEL_CALLENDAR";
        $availableGroupTypes["calendar"]["titleColumn"]["value"] = '$data->title';
        $availableGroupTypes["calendar"]["modelName"] = "Calendar";

        if (PhonalisaLicenseManager::analyticsQueueReportEnabled()) {
            $availableGroupTypes["queues"]["checkBoxColumns"]["statisticQueues"] = array('header' => 'USERGROUP_MODEL_STATISTIC_QUEUE_PERMISSION');
            $availableGroupTypes["queues"]["checkBoxColumns"]["advStatisticQueues"] = array('header' => 'USERGROUP_MODEL_ADV_STATISTIC_QUEUE_PERMISSION');
        }
        if (PhonalisaLicenseManager::adminQueueMonitorEnabled()) {
            $availableGroupTypes["queues"]["checkBoxColumns"]["monitorQueues"] = array('header' => 'USERGROUP_MODEL_MONITOR_QUEUE_PERMISSION');
            $availableGroupTypes["queues"]["checkBoxColumns"]["toggleAgentLogin"] = array('header' => 'USERGROUP_MODEL_TOGGLE_AGENT_LOGIN');
            $availableGroupTypes["queues"]["checkBoxColumns"]["moderator"] = array('header' => 'USERGROUP_MODEL_MODERATOR');
        }

        $availableGroupTypes["queues"]["titleColumn"]["title"] = "name";
        $availableGroupTypes["queues"]["titleColumn"]["label"] = "USERGROUPS_MODEL_QUEUES";
        $availableGroupTypes["queues"]["titleColumn"]["value"] = '$data->name';
        $availableGroupTypes["queues"]["additionlalCollumns"][] = array('name' => 'extension', 'header' => __('QUEUE_MODEL_EXTENSION'));
        $availableGroupTypes["queues"]["modelName"] = "Queue";


        $availableGroupTypes["forwardingSets"]["checkBoxColumns"]["read_forwardingset"] = array('header' => 'USERGROUP_MODEL_USE_FORWARDING_SET_PERMISSION');
        //$availableGroupTypes["forwardingSets"]["checkBoxColumns"]["write_forwardingset"] = array('header'=>'USERGROUP_MODEL_UPDATE_FORWARDING_SET_PERMISSION');
        $availableGroupTypes["forwardingSets"]["titleColumn"]["title"] = "name";
        $availableGroupTypes["forwardingSets"]["titleColumn"]["label"] = "FORWARD_PRESET_MODEL_NAME";
        $availableGroupTypes["forwardingSets"]["titleColumn"]["value"] = '$data->name';
        $availableGroupTypes["forwardingSets"]["additionlalCollumns"][] = array('name' => 'description', 'header' => __('FORWARD_PRESET_MODEL_DESCRIPTION'));
        $availableGroupTypes["forwardingSets"]["modelName"] = "Calendar";

        return $availableGroupTypes;
    }

    public function getColumns($permissionType, $position = 'intern')
    {
        $columns = array();
        $availableTypes = $this->availableGroupTypes();
        //FIXME give me translation tags ...
        $newRecordTranslationHtmlOptions = array();
        if (Yii::app()->user->translateMode && $permissionType == 'groups') {
            $newRecordTranslationHtmlOptions = array('data-translation-id' => 'GROUPS_MODEL_CURRENT_GROUP');
        }
        $columns[] = array(
            'header' => __($availableTypes[$permissionType]['titleColumn']['label']),
            'value' => '$data->' . $availableTypes[$permissionType]['titleColumn']['title'],
            'headerHtmlOptions' => array(
                'data-translation-id' => $availableTypes[$permissionType]['titleColumn']['label']
            ),
            'htmlOptions' => $newRecordTranslationHtmlOptions,
        );
        if (isset($availableTypes[$permissionType]['additionlalCollumns'])) {
            foreach ($availableTypes[$permissionType]['additionlalCollumns'] as $column) {
                $columns[] = $column;
            }
        }
        if ($position == 'extern') {
            $externModel = new $availableTypes[$permissionType]['modelName'];

            $render = array($externModel, 'renderPermissions');
        } else {
            $render = array($this, 'renderPermissions');
        }
        foreach ($availableTypes[$permissionType]['checkBoxColumns'] as $type => $columnAttributes) {
            $columns[] = array(
                'id' => $type,
                'headerHtmlOptions' => array('data-translation-id' => $columnAttributes['header']),
                'header' => __($columnAttributes['header']),
                'type' => 'raw',
                'value' => $render,
                'htmlOptions' => array(
                    'data-custom-contexthelp-key' => 'GROUP_' . strtoupper($type) . '_CONTEXT_HELP'
                )
            );
        }
        return $columns;
    }

    public function categoryChild($id)
    {
        $models = $this->find(array('parent' => $id), 'name');
        $children = array();
        if (count($models) > 0) {
            # It has children, let's get them.

            foreach ($models as $model) {
                $children[$model->title] = $this->categoryChild($model->id);
            }
        }
        return $children;
    }

    private function countParentGroupsRecursive($groups, $groupId, &$index = 0)
    {
        $groups[$groupId]['index'] = $index;
        foreach ($groups as $key => $group) {
            // is child group
            if ($group['parent'] == $groupId) {
                $index++;
                $groups[$key]['parentNumber'] += $groups[$groupId]['parentNumber'] + 1;
                $groups = $this->countParentGroupsRecursive($groups, $groups[$key]['id'], $index);
            }
        }
        return $groups;
    }

    private function addGroupListSpacer($groups)
    {
        $firstChar = '';
        $spacerChar = "-";
        foreach ($groups as $id => $group) {
            $groups[$id]['name'] = $firstChar
                    . str_repeat($spacerChar, $groups[$id]['parentNumber'])
                    . " "
                    . $groups[$id]['name'];
        }
        aasort($groups, "index");
        $list = CHtml::listData($groups, 'id', 'name');
        return $list;
    }

    public function getNestedGroupList($skipGroup = null)
    {
        $rootGroup = null;
        $groups = array();
        $groupModels = Groups::model()->find(array(), 'name');
        foreach ($groupModels as $groupModel) {
            // skip child groups
            if ($groupModel->parent == $skipGroup) {
                continue;
            }

            // creatre new group or load
            $group = isset($groups[$groupModel->id]) ? $groups[$groupModel->id] : array();

            $group['id'] = $groupModel->id;
            $group['parent'] = $groupModel->parent;
            $group['name'] = $groupModel->name;
            $group['parentNumber'] = 0;
            $group['index'] = 0;

            $groups[$groupModel->id] = $group;

            // Find root group
            if ($groupModel->parent == '0') {
                $rootGroup = $groupModel;
            }
        }

        $groups = $this->countParentGroupsRecursive($groups, $rootGroup->id);

        // remove current group from list
        if ($skipGroup) {
            unset($groups[$skipGroup]);
            foreach ($groups as $id => $group) {
                if ($group['parentNumber'] == 0 && $group['parent'] != '0') {
                    unset($groups[$id]);
                }
            }
        }
        return $this->addGroupListSpacer($groups);
    }

    public function updateNestedIndex()
    {
        $groups = $this->getNestedGroupList();

        $i = 0;
        foreach ($groups as $id => $nestedName) {
            $group = $this->findByPk($id);
            if ($group == null) {
                continue;
            }
            $group->nestedIndex = $i;
            $group->nestedName = $nestedName;
            $group->scenario = 'nestedIndex';
            $group->save();
            $i++;
        }
    }

    protected function findChilderen($recursive = true, $model = null)
    {
        if ($model == null) {
            $model = $this;
        }
        return $model->find(array('parent' => $model->id), 'name');
    }

    private function getChildNumberRecursive($groups, $currentId)
    {
        $summ = 0;

        foreach ($groups as $id => $group) {
            if ($group['parent'] == $currentId) {
                $summ += $group['userNumber'];
                $summ += $this->getChildNumberRecursive($groups, $group['id']);
            }
        }
        return $summ;
    }

    public function getUserNumber()
    {
        return User::model()->countByAttributes(array('group' => $this->id));
    }

    public function getUserNumbers()
    {
        $groups = array();
        $groupModels = $this->findAll();

        foreach ($groupModels as $groupModel) {
            // creatre new group or load
            $group = isset($groups[$groupModel->id]) ? $groups[$groupModel->id] : array();

            $group['id'] = $groupModel->id;
            $group['parent'] = $groupModel->parent;
            $group['name'] = $groupModel->name;
            $group['userNumber'] = User::model()->countByAttributes(array('group' => $groupModel->id));

            $groups[$groupModel->id] = $group;
        }

        foreach ($groups as $id => $group) {
            $groups[$id]['childUserNumber'] = $this->getChildNumberRecursive($groups, $id);
        }
        return $groups;
    }

    public function getChildGroups()
    {
        return $this->findAllByAttributes(array('parent' => $this->id));
    }

    public function getParentGroups()
    {
        $parentId = $this->parent;
        if ($parentId == '0') {
            return array();
        }
        $parentGroups = array();

        while ($parentId != '0') {
            $parentGroup = $this->findByPk($parentId);
            $parentId = $parentGroup->parent;
            $parentGroups[] = $parentGroup;
        }
        return $parentGroups;
    }

    public function getUsers()
    {
        return User::model()->findAllByAttributes(array('group' => $this->id));
    }

    /**
     * Returns (recursive) all parents of current group
     * @param bool $recursive search recursive
     * @return array fetched parents
     */
    public function getParents($recursive)
    {
        $parentId = $this->parent;
        $parentGroups = array();

        if ($parentId != null) {
            if ($parentId == '0') {
                return $parentGroups;
            }
            while ($parentId != '0') {
                $parentGroup = $this->findByPk($parentId);
                $parentId = $parentGroup->parent;
                $parentGroups[] = $parentGroup;
            }
        }
        return $parentGroups;
    }

    /**
     * Returns (recursive) all children of current group
     * @param bool $recursive search recursive
     * @return array fetched children
     */
    public function getChildren($recursive = false)
    {
        if ($recursive) {
            return $this->getChildrenRecursive($this);
        }
        return $this->findAllByAttributes(array('parent' => $this->id));
    }

    /**
     * Returns recursive all children of selected group
     * @param Groups model $group where to search for children
     * @param array $children children that was fetched in previous iteration
     * @return array fetched groups
     */
    private function getChildrenRecursive($group, $children = array())
    {
        $newChildren = $this->findAllByAttributes(array('parent' => $group->id));
        if ($newChildren == null) {
            return $children;
        }
        foreach ($newChildren as $newChild) {
            $nextLevelChildren = $this->getChildrenRecursive($newChild, $children);
            $diff = array_diff($nextLevelChildren, $children);
            $children = array_merge($children, $diff);
        }
        return array_merge($children, $newChildren);
    }

    public function getProvisioningProfile()
    {
        $profileID = $this->provisioningProfile;
        if ($profileID == null || $profileID == "") {
            return null;
        }
        return ProvisioningProfile::model()->findByPk($profileID);
    }

    public function __toString()
    {
        return $this->id;
    }

    public function getFormattedName()
    {
        return $this->extension != '' ? '<' . $this->extension . '> ' . $this->name : $this->name;
    }

    public function getMusicOnHoldListData()
    {
        $playlistModel = new MusicOnHold();
        $data = CHtml::listData($playlistModel->find(array(), 'name'), 'id', 'name');
        $ldata['default'] = __("DEFAULT_MOH_PLAYLIST_NAME");
        $data = array_merge($ldata, $data);
        return $data;
    }

    public function getTargetList()
    {
        $targetHelper = new TargetHelper;
        $targetList = $targetHelper->getRedirectionTargetList(false);
        if (isset($targetList[__('GROUPS')][TargetType::Group . '_' . $this->id])) {
            unset($targetList[__('GROUPS')][TargetType::Group . '_' . $this->id]);
            if (empty($targetList[__('GROUPS')])) {
                unset($targetList[__('GROUPS')]);
            }
        }
        $targetList = array_merge(array('_' => '---'), $targetList);
        return $targetList;
    }

    public function getSelectedValueForAttributes($typeValue, $value)
    {
        $targetHelper = new TargetHelper();
        return $targetHelper->getSelectedValueForAttributes($typeValue, $value, $this);
    }

    public function getGroupMembers()
    {
        $users = $this->getUsers();
        $members = array();
        foreach ($users as $user) {
            $members[$user->id] = $user;
        }
        return $members;
    }

    public function getFaxSendPermission()
    {
        $userFaxPermissions = User::getFaxSendAllowedDropdownList();
        $userFaxPermissions[User::FAX_SEND_INHERIT_FROM_GROUP] = __('GROUP_FAX_SEND_INHERIT_FROM_GROUP');
        if ($this->type == Groups::GROUP_TYPE_ALL_USERS) {
            unset($userFaxPermissions[User::FAX_SEND_INHERIT_FROM_GROUP]);
        }
        return $userFaxPermissions;
    }
}
