<?php

/**
  model class name  = ProvisioningProfile
  form-id  == provisioning-profile-form

 */
class DefaultController extends Controller
{

    /**
     * @var string the default layout for the views. Defaults to '//layouts/column2', meaning
     * using two-column layout. See 'protected/views/layouts/column2.php'.
     */
    public $layout = '//layouts/column2';

    /**
     * @return array action filters
     */
    public function filters()
    {
        return array(
            'accessControl', // perform access control for CRUD operations
        );
    }

    /**
     * Specifies the access control rules.
     * This method is used by the 'accessControl' filter.
     * @return array access control rules
     */
    public function accessRules()
    {
        return array(
            array('allow', // allow all users to perform 'index' and 'view' actions
                'actions' => array('index'),
                //'users'=>array('@'),
                'expression' => AccessManager::checkSessionPermission($this->module->name),
            ),
            array('allow', // allow authenticated user to perform 'create' and 'update' actions
                'actions' => array('create', 'update'),
                //'users'=>array('@'),
                'expression' => AccessManager::checkSessionPermission($this->module->name),
            ),
            array('allow', // allow admin user to perform 'admin' and 'delete' actions
                'actions' => array('delete'),
                //'users'=>array('@'),
                'expression' => AccessManager::checkSessionPermission($this->module->name),
            ),
            array('allow', // allow admin user to perform 'admin' and 'delete' actions
                'actions' => array('getDownloadableFile', "getDownloadableFileByHash"),
                'users' => array('*'),
            ),
            array('deny', // deny all users
                'users' => array('*'),
            ),
        );
    }

    /**
     * Creates a new model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     */
    public function actionCreate()
    {
        $model = new ProvisioningProfile();
        $defaultParameter = new PhoneParameters();
        $buffer = false;
        $bufferParameterKeys = $this->bufferParameterKeys($model);

        $this->performAjaxValidation($model);
        if (isset($_POST['ProvisioningProfile'])) {
            $model->attributes = $_POST['ProvisioningProfile'];
            if (isset($_REQUEST['phone'])) {
                $model->lastEditedPhoneType = $_REQUEST['phone'];
            }
            if ($model->save()) {
                if ($this->savePhoneParameters($model)) {
                    Yii::app()->user->setSuccessFlashMessage();
                    $this->redirect(url('/provisioningProfile/default/index'));
                } else {
                    $buffer = true;
                    $bufferParameterKeys = $this->bufferParameterKeys($model);
                    $model->delete();
                }
            } else {
                Yii::app()->user->setErrorFlashMessage();
                $buffer = true;
            }
        }
        $defaultPhoneModelName = $this->getDefaultPhoneModelName($model);
        $this->render('phoneParameterGrid', array(
            'profile' => $model,
            'defaultParameter' => $defaultParameter,
            'selectedPhone' => $defaultPhoneModelName,
            'buffer' => $buffer,
            'bufferParameterKeys' => $bufferParameterKeys,
            'phoneModel' => PhoneModelFactory::getPhoneModelOfType($defaultPhoneModelName)
        ));
    }

    /**
     * Updates a particular model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id the ID of the model to be updated
     */
    public function actionUpdate($id)
    {
        $profile = ProvisioningProfile::model()->findByPk($id);
        $defaultParameter = new PhoneParameters();
        $phoneParameters = PhoneParameters::model()->find(array('profileId' => $id), 'name');
        $buffer = false;
        $bufferParameterKeys = $this->bufferParameterKeys($profile);

        $this->performAjaxValidation($profile);

        if (isset($_POST['ProvisioningProfile'])) {
            $profile->attributes = $_POST['ProvisioningProfile'];
            if (isset($_REQUEST['phone'])) {
                $profile->lastEditedPhoneType = $_REQUEST['phone'];
            }
            if ($profile->save()) {
                if ($this->savePhoneParameters($profile)) {
                    Yii::app()->user->setSuccessFlashMessage();
                    $this->redirect(url('/provisioningProfile/default/index'));
                } else {
                    $buffer = true;
                }
            } else {
                Yii::app()->user->setErrorFlashMessage();
                $buffer = true;
            }
        }
        $defaultPhoneModelName = $this->getDefaultPhoneModelName($profile);
        $this->render('phoneParameterGrid', array(
            'profile' => $profile,
            'defaultParameter' => $defaultParameter,
            'phoneParameters' => $phoneParameters,
            'selectedPhone' => $defaultPhoneModelName,
            'buffer' => $buffer,
            'bufferParameterKeys' => $bufferParameterKeys,
            'phoneModel' => PhoneModelFactory::getPhoneModelOfType($defaultPhoneModelName)
                )
        );
    }

///TEST

    public function getPostedParams()
    {
        $postedParameters = array();
        if (isset($_POST['PhoneParameters'])) {
            foreach ($_POST['PhoneParameters']as $post) {
                if ($post['name'] != '') {
                    $postedParameters[$post['name'] . '-' . $post['meta']] = $post;
                }
            }
        }
        return $postedParameters;
    }

    public function getDefinedParams($profile)
    {
        $existingParams = $profile->getParamsForPhone($this->getDefaultPhoneModelName($profile)); // NOTE check this line when Params exsists!
        $definedParams = array();
        foreach ($existingParams as $param) {
            $definedParams[$param->name . '-' . $param->meta] = $param;
        }
        return $definedParams;
    }

    public function savePhoneParameters($profile)
    {
        $postedParameters = $this->getPostedParams($profile);
        $exstingParams = $this->getDefinedParams($profile);

        foreach ($postedParameters as $key => $attributes) {
            if (!array_key_exists($key, $exstingParams)) {
                $param = new PhoneParameters();
            } else {
                $param = $exstingParams[$key];
            }
            $param->attributes = $attributes;
            $param->profileID = $profile->id;
            $param->phoneModel = $this->getDefaultPhoneModelName($profile);
            if (!$param->save()) {
                Yii::app()->user->setErrorFlashMessage('CHANGES_NOT_SAVED_CAUSE_OF_AN_ERROR', $param->getFormatedErrors());
                return false;
            }
        }
        foreach ($exstingParams as $key => $oldparam) {
            if (!array_key_exists($key, $postedParameters)) {
                $oldparam->delete();
            }
        }
        if (count($profile->getParamsForPhone('ergoS501'))) {
            $groups = Groups::model()->findAllByAttributes(array('provisioningProfile' => $profile->id));
            foreach ($groups as $group) {
                $group->save();
            }
        }
        return $this->saveUploadableFiles($profile);
    }

    public function saveUploadableFiles($profile)
    {
        if (!isset($_FILES['UploadableFiles'])) {
            return true;
        }
        $phoneModel = PhoneModelFactory::getPhoneModelOfType($this->getDefaultPhoneModelName($profile));
        foreach ($phoneModel->getUploadableFiles() as $file) {
            // get file
            $fileName = $file['name'];
            $uploadedFile = CUploadedFile::getInstanceByName('UploadableFiles[' . $fileName . ']');

            if (!$uploadedFile) {
                continue;
            }
            if ($file['maxFileSize'] < $uploadedFile->size) {
                Yii::app()->user->setErrorFlashMessage('UPLOADED_FILE_IS_TO_LARGE');
                return false;
            }
            if ($file['type'] == 'image' && isset($file['details']['width']) && isset($file['details']['height'])) {
                $imgSize = getimagesize($uploadedFile->getTempName());

                if ($file['details']['width'] != $imgSize[0] || $file['details']['height'] != $imgSize[1]) {
                    Yii::app()->user->setErrorFlashMessage('INVALID_IMAGE_RESOLUTION');
                    return false;
                } else {
                    $profile->saveFileToFieldByPath($fileName, $uploadedFile->getTempName());
                }
            }
        }
        return true;
    }

///TEST end
    public function getDefaultPhoneModelName($model)
    {
        $phoneName = 'os15';
        if (isset($_GET['phone'])) {
            $phoneName = $_GET['phone'];
        } else if (!empty($model->lastEditedPhoneType)) {
            $phoneName = $model->lastEditedPhoneType;
        }
        return $phoneName;
    }

    /**
     * Deletes a particular model.
     * If deletion is successful, the browser will be redirected to the 'admin' page.
     * @param integer $id the ID of the model to be deleted
     */
    public function actionDelete($id)
    {
        if (Yii::app()->request->isPostRequest) {
//             we only allow deletion via POST request
            $this->loadModel($id)->delete();
//             if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
            if (!isset($_GET['ajax'])) {
                $this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('index'));
            }
        } else {
            throw new CHttpException(400, 'Invalid request. Please do not repeat this request again.');
        }
    }

    /**
     * Lists all models.
     */
    public function actionIndex()
    {
        $model = new ProvisioningProfile();
        $this->render('index', array(
            'model' => $model,
        ));
    }

    /**
     * Returns the data model based on the primary key given in the GET variable.
     * If the data model is not found, an HTTP exception will be raised.
     * @param integer the ID of the model to be loaded
     */
    public function loadModel($id)
    {
        $model = ProvisioningProfile::model()->findByPk($id);
        if ($model === null) {
            throw new CHttpException(404, 'The requested page does not exist.');
        }
        return $model;
    }

    /**
     * Performs the AJAX validation.
     * @param CModel the model to be validated
     */
    protected function performAjaxValidation($model)
    {
        if (isset($_POST['ajax']) && $_POST['ajax'] === 'provisioning-profile-form') {
            echo CActiveForm::validate($model);
            Yii::app()->end();
        }
    }

    public function render_textField($data, $row, $column)
    {
        return CHtml::activeTextField($data, $column->name, array('name' => 'PhoneParameters[' . $row . '][' . $column->name . ']'));
    }

    public function renderPhoneNamesDropdown($url = 'create')
    {
        //FIXME !
        if (isset($_GET['id'])) {
            $url = 'update&id=' . $_GET['id'];
        }
        $phone = new Phones();
        $phones = $phone->getPhoneManufactorAndModelNames();

        $items = array();

        foreach ($phones as $phoneType => $phonesArray) {
            foreach ($phonesArray as $id => $name) {
                $items[$id] = array(
                    'label' => $name,
                    'url' => url('provisioningProfile/default/' . $url, array('phone' => $id)),
                );
            }
        }
        return $items;
    }

    public function bufferParameterKeys($profile)
    {
        $postParameters = $this->getPostedParams();
        $newParam = array();

        if (isset($_POST['PhoneParameters'])) {
            foreach ($postParameters as $attributes) {
                $param = new PhoneParameters();
                $param->attributes = $attributes;
                $param->profileID = $profile->id;
                $param->phoneModel = $this->getDefaultPhoneModelName($profile);
                $newParam[] = $param;
            }
        }
        if (empty($newParam)) {
            $newParam[] = new PhoneParameters();
        }
        $dataProvider = new CArrayDataProvider($newParam, array('pagination' => false));
        return $dataProvider;
    }

    public function actionGetDownloadableFile($id, $name)
    {
        $data = "";
        $length = 0;

        $model = $this->loadModel($id);

        $phoneModelName = substr($name, 0, strpos($name, '_'));
        $phoneModel = PhoneModelFactory::getPhoneModelOfType($phoneModelName);
        if (!$phoneModel) {
            throw new CHttpException(400, 'Invalid phone model prefix.');
        }

        $uploadableFilesInfo = $phoneModel->getUploadableFiles();
        if (!isset($uploadableFilesInfo[$name]['mimeType'])) {
            Yii::app()->end();
        }

        $mimeType = $uploadableFilesInfo[$name]['mimeType'];
        if ($model != NULL && $model->getBinaryField($name, $data, $length)) {
            header('Content-type: ' . $mimeType);
            header("Content-Length: " . $length);
            echo $data;
            exit();
        }
    }

    public function actionGetDownloadableFileByHash($hash, $name)
    {
        $data = "";
        $length = 0;
        $model = ProvisioningProfile::model()->findByAttributes(array($name => $hash));
        // $model = $this->loadModel($id);
        if (!$model) {
            Yii::app()->end();
        }

        $phoneModelName = substr($name, 0, strpos($name, '_'));
        $phoneModel = PhoneModelFactory::getPhoneModelOfType($phoneModelName);
        if (!$phoneModel) {
            throw new CHttpException(400, 'Invalid phone model prefix.');
        }

        $uploadableFilesInfo = $phoneModel->getUploadableFiles();
        if (!isset($uploadableFilesInfo[$name]['mimeType'])) {
            Yii::app()->end();
        }

        $mimeType = $uploadableFilesInfo[$name]['mimeType'];
        if ($model != NULL && $model->getBinaryField($name, $data, $length)) {
            header('Content-type: ' . $mimeType);
            header("Content-Length: " . $length);
            echo $data;
            exit();
        }
    }
}
