<?php

class Users extends CActiveRecord {
    /* http://www.elisdn.ru/blog/9/bezopasnoe-hranenie-parolia-v-modeli-yii */

    const isUser = 0;
    const isBot = 5;
    const isBeast = 6;

    public $value_role;
    public $id_cat_role;
    public $new_mail;
    public $result;
    public $sum;
    public $users;
    public $period;
    public $logins;
    public $id_dialog;
    //for stats
    public $totalEnergy;
    public $totalStrength;
    public $totalHealth;
    public $totalRegeneration;
    public $totalArmor;
    public $totalSummary;

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

    /**
     * @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('totalEnergy, totalStrength, totalHealth, totalRegeneration, totalArmor, totalSummary', 'numerical', 'integerOnly' => true),
            array('id_ref, sex, class, side, battle_type, backpack_destroy, diplomat, avatar', 'numerical', 'integerOnly' => true),
            array('id_role, level, xp, money, strength, health, energy, regeneration, armor, health_now, energy_now, iron, bottles, guild_id, guild_rank, battle_id, battle_target, battle_income, battle_output, battle_time_in, battle_time_out, participation, backpack, store, premium_time, mute_time, id_ban, created, last_visit', 'length', 'max' => 11),
            array('login, email, password, ip', 'length', 'max' => 50),
            array('ua', 'length', 'max' => 500),
            array('summary, dungeon_id, logins, pumpit_id, login, email, email_remind, email_remind_time, password, class, xp, money, iron, bottles, guild_id, guild_rank, guild_invite, battle_type, battle_id, battle_target, battle_income, battle_output, battle_time_in, battle_time_out, participation, backpack_destroy, diplomat, premium_time, mute_time, id_ban, created, last_visit, ua, avatar', 'safe'),
        );
    }

    /**
     * @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(
            'idRole' => array(self::BELONGS_TO, 'Roles', 'id_role'),
            'idMail' => array(self::HAS_MANY, 'UserMail', 'id_user'),
            'idItem' => array(self::HAS_MANY, 'UserItems', 'id_user'),
            'idGuild' => array(self::BELONGS_TO, 'Guilds', 'guild_id'),
            'idBan' => array(self::BELONGS_TO, 'UserBan', 'id_ban'),
            'idTheme' => array(self::HAS_MANY, 'ForumThemes', 'id_user'),
            'idMessage' => array(self::HAS_MANY, 'ForumMessages', 'id_user'),
            'idLocation' => array(self::BELONGS_TO, 'BattlesLocations', 'battle_id'),
            'idDungeon' => array(self::BELONGS_TO, 'BattlesDungeons', 'battle_id'),
            'idTarget' => array(self::BELONGS_TO, 'Users', 'battle_target'),
            'idRef' => array(self::BELONGS_TO, 'Users', 'id_ref'),
            'dungeons' => array(self::MANY_MANY, 'DungeonsList', 'dungeons_waiters(id_user, id_dungeon)'),
            'logs' => array(self::MANY_MANY, 'BattleLog', 'log_for_users(id_user, id_log)', 'order' => 'logs.id_log DESC'),
            'forum_themes' => array(self::MANY_MANY, 'ForumThemes', 'forum_themes_for_users(id_user, id_theme)'),
            'dialogs' => array(self::MANY_MANY, 'UsersDialogs', 'users_dialogs_for_users(id_user, id_dialog)'),
            'messages' => array(self::MANY_MANY, 'UsersMessages', 'users_messages_for_users(id_user, id_messages)'),
            'items' => array(self::HAS_MANY, 'UserItems', 'id_user'),
            'buffs' => array(self::HAS_MANY, 'UsersBuffs', 'id_user'),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels() {
        return array(
            'id_user' => Yii::t('layout', 'Пользователь'),
            'id_role' => Yii::t('layout', 'Роль'),
            'ip' => Yii::t('layout', 'IP'),
            'logins' => Yii::t('layout', 'Список пользователей'),
        );
    }

    public function behaviors() {
        return array('CAdvancedArBehavior' => array(
                'class' => 'application.extensions.CAdvancedArBehavior.CAdvancedArBehavior'));
    }

    /**
     * UPD: Не выводить зверей
     * Вывод юзера, тот же findByPk, мб потом улучшаться будет
     * @param type $id
     * @return type
     */
    public static function findUser($id = null) {
        if ($id == null)
            $id = Yii::app()->user->id;
        $user = self::model()->findByPk($id);
        if (!$user || $user->id_role == 6) {
            throw new CHttpException(404, 'Данный пользователь не существует');
        } else
            return $user;
    }

    /**
     * Поиск юзера по ID с партнерок, может будут ещё и уже будет готовый велосипед для поиска
     * Если не находит пользователя то создает пустой объект
     * @param type $id ID юзера в партнерке
     * @param type $type поле в users в котором храниться ID
     * @return type 
     * @throws CHttpException
     */
    public static function findPartnerUser($id, $column = 'pumpit_id') {
        $user = self::model()->findByAttributes(array($column => $id));
        if (!$user) {
            return new Users;
        } else
            return $user;
    }

    /**
     * Считает ко-во игроков
     * @param type $side
     * @param type $class
     * @return boolean
     */
    public static function countUsers($side = 1, $class = 1) {
        $criteria = new CDbCriteria;
        $criteria->addCondition('id_role != 5');
        $criteria->addCondition('id_role != 6');
        $criteria->compare('side', $side);
        $criteria->compare('class', $class);
        return self::model()->count($criteria);
    }

    /**
     * Считает ко-во игроков и ботов
     * @param type $side
     * @param type $class
     * @return boolean
     */
    public static function countUsersWithBots($side = 1, $class = 1) {
        $criteria = new CDbCriteria;
        $criteria->compare('side', $side);
        $criteria->compare('class', $class);
        return self::model()->count($criteria);
    }

    /**
     * Проверяет есть ли у пользователя активный бан
     * @param int $id
     * @return int
     */
    public static function checkForBan($id) {
        $criteria = new CDbCriteria;
        $criteria->with = array('idBan');
        $criteria->together = true;
        $criteria->condition = 'idBan.time >= ' . time() . ' OR idBan.time = 0';
        $criteria->compare('t.id_user', $id);
        return Users::model()->count($criteria);
    }

    /**
     * Проверяет пользователь в битве или нет
     * @return int
     */
    public static function checkForBattle($battle = false) {
        if (!Yii::app()->user->isGuest) {
            $criteria = new CDbCriteria;
            $criteria->select = array('battle_type');
            $criteria->addCondition('battle_type > 0');
            $criteria->compare('t.id_user', Yii::app()->user->id);
            $user = Users::model()->find($criteria);
            if (isset($user->battle_type)) {
                return $user->battle_type;
            }
        }
        return false;
    }

    /**
     * Проверяет пользователь в битве или нет для футера
     * @param int $id
     * @return int
     */
    public static function checkForBattleToFooter() {
        $in_battle = strpos(Yii::App()->request->requestUri, '/battles/');
        $in_dungeon = strpos(Yii::App()->request->requestUri, '/dungeons/');
        $in_trainig = strpos(Yii::App()->request->requestUri, '/training/');
        if (!Yii::app()->user->isGuest && ($in_dungeon === false || $in_battle === false || $in_trainig === false)) {
            $criteria = new CDbCriteria;
            $criteria->select = array('battle_type');
            $criteria->addCondition('battle_id > 0');
            $criteria->compare('t.id_user', Yii::app()->user->id);
            $user = Users::model()->find($criteria);
            if ($user) {
                return true;
            }
        }
        return false;
    }

    /**
     * Проверяет есть ли у пользователя клан
     * @param int $id
     * @return int
     */
    public static function checkForGuild() {
        if (!Yii::app()->user->isGuest) {
            $criteria = new CDbCriteria;
            $criteria->select = array('guild_id');
            $criteria->addCondition('guild_id > 0');
            $criteria->compare('id_user', Yii::app()->user->id);
            return self::model()->find($criteria);
        }
        return false;
    }

    /**
     * Проверяет есть ли у пользователя приглашение в клан
     * @param int $id
     * @return int
     */
    public static function checkForGuildInvite() {
        if (!Yii::app()->user->isGuest) {
            $criteria = new CDbCriteria;
            $criteria->select = array('guild_invite');
            $criteria->addCondition('guild_invite > 0');
            $criteria->compare('id_user', Yii::app()->user->id);
            return self::model()->find($criteria);
        }
        return false;
    }

    /**
     * Проверяет модер или админ
     * @param int $id
     * @return int
     */
    public static function checkForPanel() {
        if (!Yii::app()->user->isGuest) {
            $criteria = new CDbCriteria;
            $criteria->with = array('idRole');
            $criteria->together = true;
            $criteria->addInCondition('idRole.id_cat_role', array(2, 3, 11));
            $criteria->compare('t.id_user', Yii::app()->user->id);
            return Users::model()->count($criteria);
        }
        return false;
    }

    /**
     * Проверяем существует ли диалог между игроками, если нет - создаем и возвращаем id
     * @param type $id_user
     * @return type
     * @throws CHttpException
     */
    public static function checkDialog($id_user, $user = null) {
        if (!$user) {
            $user = Yii::app()->user->id;
        }
        $criteria = new CDbCriteria();
        $criteria->with = array('dialogs', 'dialogs.users');
        $criteria->together = true;
        $criteria->compare('t.id_user', $user);
        $criteria->compare('users.id_user', $id_user);
        $criteria->select = 'dialogs.id_dialog as id_dialog';
        $result = Users::model()->find($criteria);
        if (!$result) {
            $result = new UsersDialogs();
            $result->time = time();
            $result->users = array($user, $id_user);
            if (!$result->save(false)) {
                throw new CHttpException(500, Yii::t('layout', 'Ошибка при сохранении истории боя!'));
            }
        }
        return $result->id_dialog;
    }

    /**
     * Выбирает юзеров для регена
     * @return type
     */
    public static function findUsersForRegeneration() {
        $criteria = new CDbCriteria();
        $criteria->select = array('t.id_user', 't.health_now', 't.energy_now',
            'IF (t.premium_time > unix_timestamp(NOW()), 50, 0) + IF (t.guild_buff_time > unix_timestamp(NOW()), 
		ROUND(SUM(items.health+items.enchant_health)*(100+t.guild_buff)/100)+t.health, 
		SUM(items.health+items.enchant_health)+t.health
		) as totalHealth',
            'IF (t.premium_time > unix_timestamp(NOW()), 50, 0) + IF (t.guild_buff_time > unix_timestamp(NOW()), 
		ROUND(SUM(items.energy+items.enchant_energy)*(100+t.guild_buff)/100)+t.energy, 
		SUM(items.energy+items.enchant_energy)+t.energy
		) as totalEnergy',
            'IF (t.premium_time > unix_timestamp(NOW()), 50, 0) + IF (t.guild_buff_time > unix_timestamp(NOW()), 
		ROUND(SUM(items.regeneration+items.enchant_regeneration)*(100+t.guild_buff)/100)+t.regeneration, 
		SUM(items.regeneration+items.enchant_regeneration)+t.regeneration
		) as totalRegeneration'
        );
        $criteria->with = array('items');
        $criteria->together = true;
        $criteria->addNotInCondition('t.id_role', array(5, 6));
        $criteria->addCondition('t.health_now > 0 AND t.last_visit > (UNIX_TIMESTAMP(NOW())-120)');
        $criteria->addCondition('items.status = 0 AND items.hardness > 0');
        $criteria->group = 't.id_user';
        $result = Users::model()->findAll($criteria);
        return $result;
    }

    /**
     * Считаем онлайн
     * @return type
     */
    public static function countOnline() {
        $criteria = new CDbCriteria();
        $criteria->condition = 't.last_visit > ' . (time() - 60 * 60);
        $criteria->addCondition('t.id_role != 5');
        $criteria->addCondition('t.id_role != 6');
        $criteria->order = 't.last_visit DESC';
        return Users::model()->count($criteria);
    }

    /**
     * Проверяет поле юзера на доступность
     * @param string $field поле в таблице юзера
     * @param int $number число, которое проверяем
     * @return int результат
     */
    public static function checkForAvailable($field, $number) {
        $criteria = new CDbCriteria;
        $criteria->condition = $field . ' >= ' . (int) $number;
        $criteria->compare('id_user', Yii::app()->user->id);
        return Users::model()->count($criteria);
    }

    /**
     * Проверяет есть ли у юзера премиум
     * @param type $id_user ид юзера
     * @return int результат
     */
    public static function checkForPremium($id_user) {
        $criteria = new CDbCriteria;
        $criteria->condition = 'premium_time >= ' . time();
        $criteria->compare('id_user', $id_user);
        return Users::model()->count($criteria);
    }

    /**
     * Если есть совпадение по IP - выводим каптчу
     * @return boolean
     */
    public function registrationCheck() {
        $criteria = new CDbCriteria;
        $criteria->compare('ip', CHttpRequest::getUserHostAddress());
        //$criteria->compare('ua', CHttpRequest::getUserAgent());
        $user = self::model()->count($criteria);

        if ($user)
            return true;
        else
            return false;
    }

    /**
     * Выводим только логин
     * @param type $id_user
     * @return null
     */
    public static function getLogin($id_user) {
        $user = self::model()->findByPk($id_user);
        if ($id_user == '-1')
            $login = 'Аукцион';
        elseif ($id_user == 0)
            $login = 'Система';
        //Если ID не существует, то имя будет такое
        elseif (!$user->login)
            $login = 'Странник';
        elseif ($user->id_role == self::isBeast)
            $login = '<img src="/images/icons/dragon.png" alt="*"/> ' . $user->login;
        else
            $login = $user->login;
        return $login;
    }

    /**
     * Выводим логин, класс, рассу пользователя
     * @param type $id_user
     * @return type
     */
    public static function getFullLogin($id_user) {
        $criteria = new CDbCriteria;
        $criteria->select = array('id_role', 'login', 'side', 'class', 'last_visit');
        $criteria->compare('id_user', $id_user);
        $user = self::model()->find($criteria);
        if (!$user || $user->id_role == self::isBeast)
            return self::getLogin($id_user);
        else {
            if ($user->last_visit < time() - 60 * 60 && $user->idRole->id_cat_role != self::isBot && $user->idRole->id_cat_role != self::isBeast)
                $off = '_offline';
            else
                $off = '';
            return '<img src="/images/icons/' . $user->side . '_' . $user->class . '' . $off . '.png" alt="' . ($user->class < 2 ? '/' : '+') . '"/> ' . $user->login;
        }
    }

    /**
     * Выводим всю информацию о пользователе и ссылку на него
     * @param type $id_user
     * @return type
     */
    public static function getLoginWithLink($id_user, $new_window = false) {
        $criteria = new CDbCriteria;
        $criteria->select = array('t.id_role');
        $criteria->compare('id_user', $id_user);
        $user = self::model()->find($criteria);
        $info = self::getFullLogin($id_user);
        if (!$user) {
            return $info;
        } elseif ($user->id_role == 6 || $user->id_role == 9)
            return $info;
        else {
            if ($new_window) {
                return CHtml::link($info, array('/user/', 'id' => $id_user), array('target' => '_blank'));
            } else {
                return CHtml::link($info, array('/user/', 'id' => $id_user));
            }
        }
    }

    /**
     * Возвращает подсчитанный шанс блока
     * @param type $value значение защиты
     * @return int
     */
    public static function getUserBlockValue($value) {
        $result = round((0.95 / (1 + 4 * pow(2.718, -0.002 * $value)) - 0.2) * 100);
        if ($result < 1)
            return 1;
        return $result;
    }

    /**
     * Возвращает подсчитанный шанс крита
     * @param type $value значение энергии
     * @return int
     */
    public static function getUserCritValue($value) {
        $result = round((0.385 / (1 + 10 * pow(2.718, -0.0011 * $value)) - 0.035) * 100);
        if ($result < 1)
            return 1;
        return $result;
    }

    public function getUserClassName() {
        return ($this->class < 2 ? 'Воин' : 'Медик');
    }

    public function getUserSideName() {
        return ($this->side < 2 ? 'Краллы' : 'Элийцы');
    }

    /**
     * Подсчитывает определенный стат у юзера
     * @param string $param название стата
     * @param int $id_user ид юзера
     * @return int знчение
     */
    public static function calcParam($id_user, $key = null) {
        $params = array(
            'strength' => 'IF (t.premium_time > unix_timestamp(NOW()), 50, 0) + IF (t.guild_buff_time > unix_timestamp(NOW()), 
			ROUND(SUM(items.strength+items.enchant_strength)*(100+t.guild_buff)/100)+t.strength, 
			SUM(items.strength+items.enchant_strength)+t.strength
			) as totalStrength',
            'health' => 'IF (t.premium_time > unix_timestamp(NOW()), 50, 0) + IF (t.guild_buff_time > unix_timestamp(NOW()), 
			ROUND(SUM(items.health+items.enchant_health)*(100+t.guild_buff)/100)+t.health, 
			SUM(items.health+items.enchant_health)+t.health
		) as totalHealth',
            'energy' => 'IF (t.premium_time > unix_timestamp(NOW()), 50, 0) + IF (t.guild_buff_time > unix_timestamp(NOW()), 
			ROUND(SUM(items.energy+items.enchant_energy)*(100+t.guild_buff)/100)+t.energy, 
			SUM(items.energy+items.enchant_energy)+t.energy
		) as totalEnergy',
            'regeneration' => 'IF (t.premium_time > unix_timestamp(NOW()), 50, 0) + IF (t.guild_buff_time > unix_timestamp(NOW()), 
			ROUND(SUM(items.regeneration+items.enchant_regeneration)*(100+t.guild_buff)/100)+t.regeneration, 
			SUM(items.regeneration+items.enchant_regeneration)+t.regeneration
		) as totalRegeneration',
            'armor' => 'IF (t.premium_time > unix_timestamp(NOW()), 50, 0) + IF (t.guild_buff_time > unix_timestamp(NOW()), 
			ROUND(SUM(items.armor+items.enchant_armor)*(100+t.guild_buff)/100)+t.armor, 
			SUM(items.armor+items.enchant_armor)+t.armor
		) as totalArmor',
            'summary' => 'IF (t.premium_time > unix_timestamp(NOW()), 50, 0) + IF (t.guild_buff_time > unix_timestamp(NOW()), 
			ROUND(SUM(items.strength+items.enchant_strength)*(100+t.guild_buff)/100)+t.strength, 
			SUM(items.strength+items.enchant_strength)+t.strength) + 
			IF (t.premium_time > unix_timestamp(NOW()), 50, 0) + IF (t.guild_buff_time > unix_timestamp(NOW()), 
			ROUND(SUM(items.health+items.enchant_health)*(100+t.guild_buff)/100)+t.health, 
			SUM(items.health+items.enchant_health)+t.health) + 
			IF (t.premium_time > unix_timestamp(NOW()), 50, 0) + IF (t.guild_buff_time > unix_timestamp(NOW()), 
			ROUND(SUM(items.energy+items.enchant_energy)*(100+t.guild_buff)/100)+t.energy, 
			SUM(items.energy+items.enchant_energy)+t.energy) + 
			IF (t.premium_time > unix_timestamp(NOW()), 50, 0) + IF (t.guild_buff_time > unix_timestamp(NOW()), 
			ROUND(SUM(items.regeneration+items.enchant_regeneration)*(100+t.guild_buff)/100)+t.regeneration, 
			SUM(items.regeneration+items.enchant_regeneration)+t.regeneration) + 
			IF (t.premium_time > unix_timestamp(NOW()), 50, 0) + IF (t.guild_buff_time > unix_timestamp(NOW()), 
			ROUND(SUM(items.armor+items.enchant_armor)*(100+t.guild_buff)/100)+t.armor, 
			SUM(items.armor+items.enchant_armor)+t.armor) as totalSummary'
        );
        $select = array('t.id_user', 't.health_now', 't.energy_now');
        if ($key)
            array_push($select, $params[$key]);
        else
            $select = array_merge($select, $params);
        $criteria = new CDbCriteria();
        $criteria->select = $select;
        $criteria->with = array('items');
        $criteria->together = true;
        $criteria->compare('t.id_user', $id_user);
        $criteria->addCondition('items.status = 0 AND items.hardness > 0');
        $result = Users::model()->find($criteria);
        if (!empty($result) && $key) {
            $values = array(
                'strength' => 'totalStrength',
                'health' => 'totalHealth',
                'energy' => 'totalEnergy',
                'regeneration' => 'totalRegeneration',
                'armor' => 'totalArmor',
                'summary' => 'totalSummary',
            );
            $field = $values[$key];
            return $result->$field;
        }
        return $result;
    }

    /**
     * Возвращает текущое кол-во ХП в процентах
     * @param type $user
     * @return type
     */
    public static function getHealthInPercents($user) {
        if ($user->id_role == 6)
            return ceil(($user->health_now * 200) / ($user->health * 2));
        else
            return ceil(($user->health_now * 200) / (Users::calcParam($user->id_user, 'health') * 2));
    }

    /**
     * Возвращает текущое кол-во энергии в процентах
     * @param type $user
     * @return type
     */
    public static function getEnergyInPercents($user) {
        if ($user->id_role == 6)
            return ceil(($user->energy_now * 200) / ($user->energy * 2));
        else
            return round(($user->energy_now * 200) / (Users::calcParam($user->id_user, 'energy') * 2));
    }

    /**
     * Подсчитываем кол-во юзеров на локации
     * @param int $side сторона, которую считаем
     * @param int $side класс, который считаем
     * @param int $id_location ид локации
     * @return int 
     */
    public static function getUsersInLocation($id_location, $side = null, $class = null) {
        $criteria = new CDbCriteria();
        $criteria->addCondition('health_now > 0');
        $criteria->compare('side', $side);
        $criteria->compare('class', $class);
        $criteria->compare('battle_type', 1);
        $criteria->compare('battle_id', $id_location);
        return self::model()->count($criteria);
    }

    /**
     * Подсчитываем кол-во ботов на локации
     * @param int $side сторона, которую считаем
     * @param int $side класс, который считаем
     * @param int $id_location ид локации
     * @return int 
     */
    public static function getBotsInLocation($id_location, $side = null, $class = null) {
        $criteria = new CDbCriteria();
        $criteria->addCondition('health_now > 0');
        $criteria->addInCondition('id_role', array(5, 6));
        $criteria->compare('side', $side);
        $criteria->compare('class', $class);
        $criteria->compare('battle_type', 1);
        $criteria->compare('battle_id', $id_location);
        return self::model()->count($criteria);
    }

    /**
     * Выводит случайных ботов для удара в Битвах
     * @param type $id_location локация
     * @param type $side сторона игрока, если не указана выводит 2х ботов
     * @return type
     */
    public static function getRandomBotsInLocationForAttack($id_location, $side = null) {
        $criteria = new CDbCriteria();
        $criteria->addCondition('id_role = 5');
        $criteria->addCondition('health_now > 0');
        $criteria->compare('battle_type', 1);
        $criteria->compare('battle_id', $id_location);
        if ($side) {
            $criteria->addCondition('side <>' . $side);
            return self::model()->find($criteria);
        } else {
            $criteria->order = 'RAND()';
            $criteria->limit = 1;
            $criteria->compare('side', 1);
            $side1 = self::model()->findAll($criteria);
            unset($criteria);
            $criteria = new CDbCriteria();
            $criteria->addCondition('id_role = 5');
            $criteria->addCondition('health_now > 0');
            $criteria->compare('battle_type', 1);
            $criteria->compare('battle_id', $id_location);
            $criteria->compare('side', 2);
            $criteria->order = 'RAND()';
            $criteria->limit = 1;
            $side2 = self::model()->findAll($criteria);
            $bots = array_merge($side1, $side2);
            return $bots;
        }
    }

    /**
     * Отнимает здоровье у случайного бота, делается для союзных  медиков, чтоб было кого лечить
     * @param type $id_location локация
     * @param type $side сторона игрока, если не указана выводит 2х ботов
     * @return type
     */
    public static function getRandomBotsInLocationForDamage($id_location, $side = null) {
        $criteria = new CDbCriteria();
        $criteria->select = array('t.id_user', 't.health_now', 'SUM(items.health)+t.health as totalHealth');
        $criteria->with = array('items');
        $criteria->together = true;
        $criteria->compare('t.battle_type', 1);
        $criteria->compare('t.id_role', 5);
        $criteria->compare('t.battle_id', $id_location);
        $criteria->compare('t.side', $side > 0 ? $side : 0);
        $criteria->addCondition('t.health_now > 100 AND items.status = 0');
        $criteria->group = 't.id_user';
        $criteria->order = 'RAND()';
        $criteria->limit = 1;
        $bot = Users::model()->find($criteria);

        if (!empty($bot)) {
            $bot->health_now -= round($bot->totalHealth / 20);
            if ($bot->health_now < 100)
                $bot->health_now = rand(75, 125);
            $bot->save(false);
        }
        return true;
    }

    /**
     * Выводит случайного соперника для боев в Битвах
     * @param type $id_location локация
     * @param type $side сторона игрока
     * @param type $is_bot если это бот, значит ему выбираем только игроков
     * @param type $id_heal если это медик, значит ему выбираем еще тех у кого есть энергия
     * @return type
     */
    public static function getRandomEnemyForBattles($id_location, $side, $is_bot = false, $id_heal = false) {
        $criteria = new CDbCriteria();
        $criteria->addCondition('health_now > 0 AND side <>' . $side);
        if ($id_heal) {
            $criteria->addCondition('energy_now > 0');
        }
        if ($is_bot) {
            $criteria->addCondition('id_role != 5');
        }
        $criteria->compare('battle_type', 1);
        $criteria->compare('battle_id', $id_location);
        $criteria->order = 'RAND()';
        $criteria->limit = 1;
        return self::model()->find($criteria);
    }

    /**
     * Выводит того кто в таргете для боев в Битвах
     * @param type $user игрок
     * @param type $id_heal если это медик, значит ему выбираем еще тех у кого есть энергия
     * @return type
     */
    public static function getLastTargetForBattles($user, $is_heal = false) {
        $criteria = new CDbCriteria();
        $criteria->addCondition('health_now > 0');
        $criteria->addCondition('battle_id = ' . $user->battle_id);
        if ($is_heal) {
            $criteria->addCondition('energy_now > 0');
        }
        $criteria->compare('battle_type', 1);
        $criteria->compare('id_user', $user->battle_target);
        return self::model()->find($criteria);
    }

    /**
     * Выводит того, кто в таргете для лечения
     * @param type $user
     * @return type
     */
    public static function getLastHealTargetForBattles($user) {
        $criteria = new CDbCriteria();
        $criteria->addCondition('health_now > 0');
        $criteria->addCondition('battle_id = ' . $user->battle_id);
        $criteria->compare('battle_type', 1);
        $criteria->compare('id_user', $user->battle_target);
        return self::model()->find($criteria);
    }

    /**
     * Выводит случайного соперника для боев в Пещерах
     * @param type $id_battle локация
     * @return type
     */
    public static function getRandomBeastInDungeons($id_battle) {
        $criteria = new CDbCriteria();
        $criteria->addCondition('health_now > 0');
        $criteria->compare('id_role', 6);
        $criteria->compare('battle_type', 2);
        $criteria->compare('battle_id', $id_battle);
        $criteria->order = 'RAND()';
        $criteria->limit = 1;
        return self::model()->find($criteria);
    }

    /**
     * Выдает всем мертвым ботам по 200% ХП и энергии
     * @param type $id_location локация
     * @return type
     */
    public static function setFullParamsForBotsInLocation($id_location) {
        $criteria = new CDbCriteria();
        $criteria->addCondition('t.health_now < 1');
        $criteria->addCondition('t.id_role = 5');
        $criteria->addCondition('t.battle_id = ' . $id_location);
        $bots = self::model()->findAll($criteria);
        foreach ($bots as $bot) {
            $params = Users::calcParam($bot->id_user);
            $bot->health_now = round($params->totalHealth * 1.45);
            $bot->energy_now = round($params->totalEnergy * 1.95);
            if (!$bot->save(false)) {
                throw new CHttpException(500, Yii::t('layout', 'Ошибка при сохранении бота!'));
            }
        }
        return true;
    }

    /**
     * Выводит случайного союзника для боев в битвах
     * @param type $id_location локация
     * @param type $side сторона игрока
     * @return type
     */
    public static function getRandomFriendForBattles($id_location, $side) {
        $criteria = new CDbCriteria();
        $criteria->with = array('items');
        $criteria->together = true;
        $criteria->select = array('id_user', 'health_now');
        $criteria->compare('battle_type', 1);
        $criteria->compare('side', $side);
        $criteria->compare('battle_id', $id_location);
        $criteria->addCondition('t.health_now > 0 AND items.status = 0 AND items.hardness > 0');
        $criteria->order = 'RAND()';
        $users = self::model()->findAll($criteria);
        $id = null;
        $ids = array();
        if (!empty($users)) {
            foreach ($users as $user) {
                if ($user->health_now < Users::calcParam($user->id_user, 'health')*2) {
                    $ids[] = $user->id_user;
                }
            }
            if (!empty($ids)) {
                $key = array_rand($ids);
                $id = $ids[$key];
            }
        }
        return self::model()->findByPk($id);
    }

    /**
     * Выводит случайного союзника для боев в Пещерах
     * @param type $id_battle локация
     * @return type
     */
    public static function getRandomFriendForDungeons($id_battle) {
        $criteria = new CDbCriteria();
        $criteria->with = array('items');
        $criteria->together = true;
        $criteria->select = array('id_user', 'health_now');
        $criteria->compare('battle_type', 2);
        $criteria->compare('battle_id', $id_battle);
        $criteria->addCondition('t.id_role != 6 AND t.health_now > 0 AND items.status = 0 AND items.hardness > 0');
        $criteria->order = 'RAND()';
        $users = self::model()->findAll($criteria);
        $id = null;
        $ids = array();
        if (!empty($users)) {
            foreach ($users as $user) {
                if ($user->health_now < Users::calcParam($user->id_user, 'health')*2) {
                    $ids[] = $user->id_user;
                }
            }
            if (!empty($ids)) {
                $key = array_rand($ids);
                $id = $ids[$key];
            }
        }
        return self::model()->findByPk($id);
    }

    /**
     * Возвращает пользователей, которым пишутся в лог действия относительно данного пользователя
     * @param type $id_user
     * @return type
     */
    public static function getUsersForLog($id_user, $battle_id = null, $type = null) {
        $criteria = new CDbCriteria();
        if ($battle_id) {
            $criteria->addCondition('id_role <> 5 AND health_now > 0 AND battle_id = ' . $battle_id);
        } else
            $criteria->addCondition('id_role <> 5 AND health_now > 0 AND (id_user = ' . $id_user . ' OR battle_target = ' . $id_user . ')');
        $users = CHtml::listData(self::model()->findAll($criteria), 'id_user', 'id_user');
        return $users;
    }

    /**
     * Выводит лидера по участию для выдачи вещи в башнях
     * @param type $id_location локация
     * @return type
     */
    public static function getParticipationLeaderForBattles($id_location) {
        $criteria = new CDbCriteria();
        $criteria->condition = 'health_now > 0';
        $criteria->compare('battle_type', 1);
        $criteria->compare('battle_id', $id_location);
        $criteria->order = 'participation DESC';
        $criteria->limit = 1;
        return self::model()->find($criteria);
    }

    /**
     * Выводит случайного зверя для удара в Пещерах
     * @param type $id_battle ид боя
     * @return type
     */
    public static function getRandomBotInDungeonForAttack($id_battle) {
        $criteria = new CDbCriteria();
        $criteria->condition = 'id_role = 6';
        $criteria->addCondition('health_now > 0');
        $criteria->compare('battle_type', 2);
        $criteria->compare('battle_id', $id_battle);
        $criteria->order = 'RAND()';
        return self::model()->find($criteria);
    }

    public function online() {
        $criteria = new CDbCriteria;
        $criteria->condition = 't.last_visit > ' . (time() - 60 * 60);
        $criteria->addCondition('t.id_role != 5');
        $criteria->addCondition('t.id_role != 6');

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
            'sort' => array(
                'defaultOrder' => 'xp DESC',
            ),
            'pagination' => array(
                'route' => '/online/',
                'params' => array(),
                'pageVar' => 'page',
                'pageSize' => '10',
            ),
        ));
    }

    public function searchByIp($pagination = true) {
        $criteria = new CDbCriteria;
        $criteria->select = '*, GROUP_CONCAT(login SEPARATOR "//") as logins';
        $criteria->addCondition('ip > 0 AND id_ban < 1');
        $criteria->addNotInCondition('id_role', array(5, 6, 7, 8));
        $criteria->group = 'ip';
        $criteria->order = 'count(login) DESC, ip ASC';

        $criteria->compare('INET_NTOA(ip)', $this->ip, true);
        $criteria->compare('login', $this->logins, true);

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
            'pagination' => FuncHelper::pagination($pagination),
        ));
    }

    public function search($pagination = true) {
        $criteria = new CDbCriteria;
        $criteria->together = true;

        $criteria->compare('id_user', $this->id_user);

        return new CActiveDataProvider($this, array(
            'criteria' => $criteria,
            'sort' => array(
//                'defaultOrder' => 'created DESC',
//                'attributes' => array(
//                    'city_id' => array('asc' => 'idEnt.city_id', 'desc' => 'idEnt.city_id DESC'),
//                    'region_id' => array('asc' => 'city.region_id', 'desc' => 'city.region_id DESC'),
//                    'country_id' => array('asc' => 'region.country_id', 'desc' => 'region.country_id DESC'),
//                    'login' => array('asc' => 't.login', 'desc' => 't.username DESC'),
//                    'email' => array('asc' => 't.email', 'desc' => 't.email DESC'),
//                    'password' => array('asc' => 't.password', 'desc' => 't.password DESC'),
//                    'created' => array('asc' => 't.created', 'desc' => 't.created DESC'),
//                    'last_visit' => array('asc' => 't.last_visit', 'desc' => 't.last_visit DESC'),
//                ),
            ),
            'pagination' => FuncHelper::pagination($pagination),
        ));
    }

    protected function beforeSave() {
        if ($this->isNewRecord) {
            if ($this->id_role != 6) {
                $this->password = md5(md5($this->password));
            }
            $this->created = time();
        }
        return parent::beforeSave();
    }

    public static function model($className = __CLASS__) {
        return parent::model($className);
    }

    public function getColumns() {
        return array(
            array(
                'name' => 'ip',
                'type' => 'raw',
                'value' => 'long2ip($data->ip)',
                'filter' => FuncHelper::getSearchFilter($this, 'ip'),
                'headerHtmlOptions' => array('class' => 'w_10p'),
            ),
            array(
                'name' => 'logins',
                'type' => 'raw',
                'value' => '$data->getComparedLogins()',
                'filter' => FuncHelper::getSearchFilter($this, 'logins'),
                'headerHtmlOptions' => array('class' => 'w_90p'),
            ),
        );
    }

    public function getComparedLogins() {
        if (!empty($this->logins)) {
            $result = array();
            $logins = explode('//', $this->logins);
            foreach ($logins as $login) {
                $user = Users::model()->findByAttributes(array('login' => $login));
                if ($user) {
                    $result[] = '<div class="col-sm-2">' . Users::getLoginWithLink($user->id_user, true) . '</div><div class="col-sm-1">[' . $user->level . ' ур.]</div> <div class="col-sm-9">UA: ' . $user->ua . '</div>';
                } else {
                    $result[] = '<div class="col-sm-12">' . $login . '</div>';
                }
            }
            $result = implode('<div class="col-sm-12"><hr></div>', $result);
            return $result;
        }
    }

}
