<?php

/**
 * Copyright (c) 2013, Kairat Bakytow
 * All rights reserved.

 * ATTENTION: This commercial software is intended for use with Oxwall Free Community Software http://www.oxwall.org/
 * and is licensed under Oxwall Store Commercial License.
 * Full text of this license can be found at http://www.oxwall.org/store/oscl
 */

/**
 *
 * @author Kairat Bakytow
 * @package ow_plugins.smileys.controllers
 * @since 1.0
 */
class SMILEYS_CTRL_Admin extends ADMIN_CTRL_Abstract
{
    private $plugin;
    private $service;
    
    public function __construct()
    {
        parent::__construct();
        
        $this->plugin = OW::getPluginManager()->getPlugin( 'smileys' );
        $this->service = SMILEYS_BOL_Service::getInstance();
        
        $language = OW::getLanguage();
        
        $language->addKeyForJs( 'smileys', 'upload_smileys' );
        $language->addKeyForJs( 'smileys', 'rename_category' );
        $language->addKeyForJs( 'smileys', 'delete_category' );
        $language->addKeyForJs( 'smileys', 'floatbox_smileys_upload_caption' );
        $language->addKeyForJs( 'smileys', 'message_smile_move_error' );
        $language->addKeyForJs( 'smileys', 'new_category' );
        $language->addKeyForJs( 'smileys', 'message_smile_move' );
    }
    
    public function index( array $params = array() )
    {
        $document = OW::getDocument();

        if ( file_exists(OW::getPluginManager()->getPlugin('BASE')->getStaticJsUrl() . 'jquery-ui-1.8.9.custom.min.js') )
        {
            $document->addScript( OW::getPluginManager()->getPlugin('BASE')->getStaticJsUrl() . 'jquery-ui-1.8.9.custom.min.js');
        }
        else
        {
            $document->addScript( $this->plugin->getStaticJsUrl() . 'jquery-ui-1.10.3.custom.min.js' );
        }
        
        $document->addScript( $this->plugin->getStaticJsUrl() . 'smileys-admin.js', 'text/javascript', 1001 );
        
        $newCategoryForm = new NewCategory();
        $this->addForm( $newCategoryForm );
        
        $uploadSmileys = new UploadSmileys();
        $this->addForm( $uploadSmileys );
        
        $themeForm = new Smileys_ThemesForm();
        $this->addForm( $themeForm );
        
        if ( OW::getRequest()->isPost() )
        {
            switch ( $_POST['command'] )
            {
                case 'createNewCategory':
                    if ( $newCategoryForm->isValid($_POST) )
                    {
                        $category = $newCategoryForm->getElement( 'categoryName' )->getValue();
                        $dir = $this->plugin->getUserFilesDir() . 'images' . DS . $category;
                        @mkdir( $dir );
                        OW::getFeedback()->info( OW::getLanguage()->text('smileys', 'message_category_created', array('categoryName' => $category)) );
                    }
                    else
                    {
                        $error = $newCategoryForm->getElement( 'categoryName' )->getErrors();
                        OW::getFeedback()->error( $error[0] );
                    }
                    break;
                case 'renameCategory':
                    if ( $newCategoryForm->isValid($_POST) )
                    {
                        $dir = $this->plugin->getUserFilesDir() . 'images' . DS;                            
                        @rename( $dir . $newCategoryForm->getElement('oldName')->getValue(), $dir . $newCategoryForm->getElement('categoryName')->getValue() );
                        OW::getFeedback()->info( OW::getLanguage()->text('smileys', 'message_category_renamed', array('categoryName' => $newCategoryForm->getElement('categoryName')->getValue())) );
                    }
                    else
                    {
                        $error = $newCategoryForm->getElement( 'categoryName' )->getErrors();
                        OW::getFeedback()->error( $error[0] );
                    }
                    break;
                case 'deleteCategory':
                        UTIL_File::removeDir( $this->plugin->getUserFilesDir() . 'images' . DS . trim(strtolower($_POST['categoryName'])) );
                        OW::getFeedback()->info( OW::getLanguage()->text('smileys', 'message_category_deleted', array('categoryName' => $_POST['categoryName'])) );
                    break;
                case 'uploadSmileys':
                    if ( $uploadSmileys->isValid($_POST) )
                    {
                        $language = OW::getLanguage();
                        $feedback = OW::getFeedback();
                        $_FILES['smileys']['name'] = array_map( 'strtolower', $_FILES['smileys']['name'] );
                        $dir = $this->plugin->getUserFilesDir() . 'images' . DS . $uploadSmileys->getElement('category')->getValue() . DS;
                        
                        foreach ( $_FILES['smileys']['error'] as $key => $val )
                        {
                            if ( $val !== 0 )
                            {
                                continue;
                            }
                            
                            if( $_FILES['smileys']['type'][$key] != 'image/gif' )
                            {
                                $feedback->error( $language->text('smileys', 'message_type_error', array('file' => $_FILES['smileys']['name'][$key])) );
                                continue;
                            }
                            
                            if ( preg_match('/^[[:word:] -]{1,20}.gif$/', $_FILES['smileys']['name'][$key]) === 0 )
                            {
                                $feedback->error( $language->text('smileys', 'message_smile_not_available', array('smile' => $_FILES['smileys']['name'][$key])) );
                                continue;
                            }
                            
                            if ( file_exists($dir . $_FILES['smileys']['name'][$key]) )
                            {
                                $feedback->error( $language->text('smileys', 'message_smile_exist', array('file' => $_FILES['smileys']['name'][$key])) );
                                continue;
                            }
                            
                            move_uploaded_file( $_FILES['smileys']['tmp_name'][$key], $dir . $_FILES['smileys']['name'][$key] );
                            $feedback->info( $language->text('smileys', 'message_smile_uploaded') );
                        }
                    }
                    break;
                case 'changeTheme':
                    $options = $themeForm->getElement( 'themeList' )->getOptions();
                    
                    if ( $themeForm->isValid($_POST) )
                    {
                        OW::getConfig()->saveConfig( 'smileys', 'theme', $options[$themeForm->getElement('themeList')->getValue()] );
                    }
                    break;
            }
            
            $newCategoryForm->reset();
        }
    }
    
    public function smileysRsp()
    {
        if ( OW::getRequest()->isAjax() && OW::getRequest()->isPost() )
        {
            $_POST = array_map( 'strtolower', array_map('trim', $_POST) );
            
            switch ( $_POST['command'] )
            {
                case 'move':
                    if ( !empty($_POST['smileys']) && !empty($_POST['oldCategory']) && !empty($_POST['newCategory']) )
                    {
                        $dir = $this->plugin->getUserFilesDir() . 'images' . DS; 
                        
                        if ( file_exists($dir . $_POST['newCategory'] . DS . $_POST['smileys']) )
                        {
                            exit( json_encode(array('result' => FALSE, 'smile' => $_POST['smileys'], 'category' => $_POST['newCategory'])) );
                        }
                        else
                        {
                            @rename( $dir . $_POST['oldCategory'] . DS . $_POST['smileys'], $dir . $_POST['newCategory'] . DS . $_POST['smileys'] );
                            exit( json_encode(array('result' => TRUE)) );
                        }
                    }
                    break;
                case 'delete':
                    @unlink( $this->plugin->getUserFilesDir() . 'images' . DS . $_POST['category'] . DS . $_POST['smileys'] );
                    exit( json_encode(array('result' => TRUE)) );
            }
        }
    }
}

class SmileysForm extends Form
{
    public function isValid( $data )
    {
        $valid = true;

        if ( !is_array($data) )
        {
            throw new InvalidArgumentException('Array should be provided for validation!');
        }

        foreach ( $this->elements as $element )
        {
            $element->setValue( isset($data[$element->getName()]) ? strtolower(trim($data[$element->getName()])) : null );

            if ( !$element->isValid() )
            {
                $valid = false;
            }
        }

        return $valid;
    }
}

class NewCategory extends SmileysForm
{
    public function __construct()
    {
        parent::__construct( 'newCategory' );
        
        $hidden = new HiddenField( 'command' );
        $hidden->setValue( 'createNewCategory' );
        $this->addElement( $hidden );
        
        $hidden = new HiddenField( 'oldName' );
        $this->addElement( $hidden );
        
        $category = new TextField( 'categoryName' );
        $category->setRequired();
        $category->addAttribute( 'maxlength', 20 );
        $dirValidator = new DirValidator();
        $category->addValidator( $dirValidator );
        $category->setLabel( OW::getLanguage()->text('smileys', 'new_category_label') );
        $this->addElement( $category );
        
        $submit = new Submit( 'save' );
        $submit->setValue( OW::getLanguage()->text('smileys', 'new_category_save') );
        $this->addElement( $submit );
    }
}

class UploadSmileys extends SmileysForm
{
    public function __construct()
    {
        parent::__construct( 'uploadSmileys' );
        
        $this->setEnctype( 'multipart/form-data' );
        
        $hidden = new HiddenField( 'command' );
        $hidden->setValue( 'uploadSmileys' );
        $this->addElement( $hidden );
        
        $hidden = new HiddenField( 'category' );
        $this->addElement( $hidden );
        
        $file = new FileField( 'smileys[]' );
        $this->addElement( $file );
        
        $submit = new Submit( 'save' );
        $submit->setValue( OW::getLanguage()->text('smileys', 'upload_smileys') );
        $this->addElement( $submit );
    }
}

class Smileys_ThemesForm extends Form
{
    public function __construct()
    {
        parent::__construct( 'themeForm' );
        
        $hidden = new HiddenField( 'command' );
        $hidden->setValue( 'changeTheme' );
        $this->addElement( $hidden );
        
        $themes = new Selectbox( 'themeList' );
        $themes->setRequired();
        $themes->setLabel( OW::getLanguage()->text('smileys', 'theme_label') );
        
        $themesList = SMILEYS_BOL_Service::getInstance()->getThemeList();                
        $themes->setOptions( $themesList );
        $themes->setValue( array_search(OW::getConfig()->getValue('smileys', 'theme'), $themesList) );
        $this->addElement( $themes );
        
        $validator = new SelectboxValidator( $themesList );
        $themes->addValidator( $validator );
        
        $submit = new Submit( 'save' );
        $submit->setValue( OW::getLanguage()->text('smileys', 'new_category_save') );
        $this->addElement( $submit );
    }
}

class SelectboxValidator extends OW_Validator
{
    private $options;
    
    public function __construct( array $options )
    {
        $this->options = $options;
    }

    public function isValid( $value )
    {
        return array_key_exists( $value, $this->options );
    }
}

class DirValidator extends OW_Validator
{
    public function __construct()
    {
        $this->errorMessage = OW::getLanguage()->text('smileys', 'message_category_invalid');
    }
    
    public function getJsValidator()
    {
        return '
        {
            validate : function( value )
            {
                if ( !/^[ \w-]{1,20}$/.test($.trim(value)) )
                {
                    throw ' . json_encode( $this->getError() ) . ';
                    return false;
                }
            },
            
            getErrorMessage : function()
            {
                return ' . json_encode($this->getError()) . ';
            }
        }';
    }

    public function isValid( $value )
    {        
        if ( preg_match('/^[[:word:] -]{1,20}$/', $value) !== 0 )
        {
            $categories = SMILEYS_BOL_Service::getInstance()->getSmilesCategories();

            if ( array_search( $value, $categories) !== FALSE )
            {
                $this->setErrorMessage( OW::getLanguage()->text('smileys', 'message_category_invalid_or_exist', array('categoryName' => $value)) );
                return FALSE;
            }
            
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }
}
