<?php

/*
 +--------------------------------------------------------------------+
 | CiviCRM version 3.0                                                |
 +--------------------------------------------------------------------+
 | Copyright CiviCRM LLC (c) 2004-2009                                |
 +--------------------------------------------------------------------+
 | This file is a part of CiviCRM.                                    |
 |                                                                    |
 | CiviCRM is free software; you can copy, modify, and distribute it  |
 | under the terms of the GNU Affero General Public License           |
 | Version 3, 19 November 2007.                                       |
 |                                                                    |
 | CiviCRM is distributed in the hope that it will be useful, but     |
 | WITHOUT ANY WARRANTY; without even the implied warranty of         |
 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
 | See the GNU Affero General Public License for more details.        |
 |                                                                    |
 | You should have received a copy of the GNU Affero General Public   |
 | License along with this program; if not, contact CiviCRM LLC       |
 | at info[AT]civicrm[DOT]org. If you have questions about the        |
 | GNU Affero General Public License or the licensing of CiviCRM,     |
 | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
 +--------------------------------------------------------------------+
*/

/**
 *
 * @package CRM
 * @copyright CiviCRM LLC (c) 2004-2009
 * $Id$
 *
 */

require_once 'CRM/Member/Form.php';

/**
 * This class generates form components for Membership Type
 * 
 */
class CRM_Member_Form_MembershipType extends CRM_Member_Form
{
    /**
     * max number of contacts we will display for membership-organisation
     */
    const MAX_CONTACTS = 50;

    /**
     * This function sets the default values for the form. MobileProvider that in edit/view mode
     * the default values are retrieved from the database
     * 
     * @access public
     * @return None
     */
    public function setDefaultValues( ) 
    {
        $defaults = array( );
        $defaults =& parent::setDefaultValues( );
        
        //finding default weight to be put 
        if ( !isset  ( $defaults['weight'] ) ||( ! $defaults['weight'] ) ) {
            $defaults['weight'] = CRM_Utils_Weight::getDefaultWeight('CRM_Member_DAO_MembershipType');
        }
        //setting default relationshipType
        if ( isset ( $defaults['relationship_type_id'] ) ) {
            //$defaults['relationship_type_id'] = $defaults['relationship_type_id'].'_a_b';
            $defaults['relationship_type_id'] = $defaults['relationship_type_id'].'_'.$defaults['relationship_direction'];
        }
        
        $config =& CRM_Core_Config::singleton( );
        //setting default fixed_period_start_day & fixed_period_rollover_day
        $periods = array('fixed_period_start_day',  'fixed_period_rollover_day');
        foreach ( $periods as $per ) {
            if (isset ( $defaults[$per] ) ) {
                $dat = $defaults[$per];
                $dat = ( $dat < 999) ? '0'.$dat : $dat; 
                $defaults[$per] = array();
                $defaults[$per][$config->dateformatMonthVar] = substr($dat, 0, 2);
                $defaults[$per]['d'] = substr($dat, 2, 3);
            }
        }

        return $defaults;
    }

    /**
     * Function to build the form
     *
     * @return None
     * @access public
     */
    public function buildQuickForm( ) 
    {
        parent::buildQuickForm( );

        if ($this->_action & CRM_Core_Action::DELETE ) { 
            return;
        }

        $this->applyFilter('__ALL__', 'trim');
        $this->add('text', 'name', ts('Name'), CRM_Core_DAO::getAttribute( 'CRM_Member_DAO_MembershipType', 'name' ), true );

        $this->addRule( 'name', ts('A membership type with this name already exists. Please select another name.'), 
                        'objectExists', array( 'CRM_Member_DAO_MembershipType', $this->_id ) );
        $this->add('text', 'description', ts('Description'), 
                   CRM_Core_DAO::getAttribute( 'CRM_Member_DAO_MembershipType', 'description' ) );
        $this->add('text', 'minimum_fee', ts('Minimum Fee'), 
                   CRM_Core_DAO::getAttribute( 'CRM_Member_DAO_MembershipType', 'minimum_fee' ) );
        $this->addRule( 'minimum_fee', ts('Please enter a monetary value for the Minimum Fee.'), 'money' );

        $this->addElement('select', 'duration_unit', ts('Duration') . ' ',
                   CRM_Core_SelectValues::unitList('duration'), array( 'onchange' => 'showHidePeriodSettings()'));
        //period type
        $this->addElement('select', 'period_type', ts('Period Type'), 
                          CRM_Core_SelectValues::periodType( ), array( 'onchange' => 'showHidePeriodSettings()'));
        
        $this->add('text', 'duration_interval', ts('Duration Interval'), 
                   CRM_Core_DAO::getAttribute( 'CRM_Member_DAO_MembershipType', 'duration_interval' ) );

        $memberOrg =& $this->add('text', 'member_org', ts('Membership Organization'), 'size=30 maxlength=120' );
        //start day
        $this->add('date', 'fixed_period_start_day', ts('Fixed Period Start Day'), 
                   CRM_Core_SelectValues::date('custom', 3, 1, "M\001d"), false);
        
        //rollover day
        $this->add('date', 'fixed_period_rollover_day', ts('Fixed Period Rollover Day'), 
                   CRM_Core_SelectValues::date('custom', 3, 1, "M\001d"), false);
        
        $this->add('hidden','action',$this->_action); //required in form rule

        require_once 'CRM/Contribute/PseudoConstant.php';
        $this->add('select', 'contribution_type_id', ts( 'Contribution Type' ), 
                   array(''=>ts( '- select -' )) + CRM_Contribute_PseudoConstant::contributionType( ) );

        require_once 'CRM/Contact/BAO/Relationship.php';
        $relTypeInd =  CRM_Contact_BAO_Relationship::getContactRelationshipType( null, null, null, null, true );
        if ( is_array($relTypeInd) ) {
            asort($relTypeInd);
        }
        $memberRel =& $this->add('select', 'relationship_type_id', ts('Relationship Type'),  array('' => ts('- select -')) + $relTypeInd);

        $this->add( 'select', 'visibility', ts('Visibility'), CRM_Core_SelectValues::memberVisibility( ) );
        $this->add('text', 'weight', ts('Order'), 
                   CRM_Core_DAO::getAttribute( 'CRM_Member_DAO_MembershipType', 'weight' ) );
        $this->add('checkbox', 'is_active', ts('Enabled?'));
                                            
        require_once "CRM/Core/BAO/MessageTemplates.php";
        $msgTemplates = CRM_Core_BAO_MessageTemplates::getMessageTemplates();
        if ( ! empty( $msgTemplates ) ) { 
            $reminderMsg = $this->add( 'select', 'renewal_msg_id', ts('Renewal Reminder Message'), array('' => ts('- select -')) + $msgTemplates );
        } else {
            $this->assign('noMsgTemplates', true );            
        }
        $reminderDay =& $this->add('text',
                                   'renewal_reminder_day',
                                   ts('Renewal Reminder Day'),
                                   CRM_Core_DAO::getAttribute( 'CRM_Member_DAO_MembershipType',
                                                               'renewal_reminder_day' ) );
        
        $searchRows            = $this->get( 'searchRows'    );
        $searchCount           = $this->get( 'searchCount'   );
        $searchDone            = $this->get( 'searchDone' );
        
        if ( $searchRows ) {
            $checkBoxes = array( );
            $chekFlag = 0;
            foreach ( $searchRows as $id => $row ) {
                $checked = '';
                if (!$chekFlag) {
                    $checked = array( 'checked' => null);
                    $chekFlag++;
                }
                
                $checkBoxes[$id] = $this->createElement('radio',null, null,null,$id, $checked );
            }
            
            $this->addGroup($checkBoxes, 'contact_check');
            $this->assign('searchRows', $searchRows );
        }

        $this->assign('searchCount', $searchCount);
        $this->assign('searchDone', $searchDone);
        
        if ( $searchDone ) {
            $searchBtn = ts('Search Again');
        } elseif ( $this->_action & CRM_Core_Action::UPDATE ) {
            $searchBtn = ts('Change');
        } else {
            $searchBtn = ts('Search');
        }
        $membershipRecords = false;
        if ( $this->_action & CRM_Core_Action::UPDATE ) {
            require_once 'CRM/Member/BAO/Membership.php';
            $membershipType = new CRM_Member_BAO_Membership();
            $membershipType->membership_type_id = $this->_id;
            if ( $membershipType->find( true ) ) {
                $membershipRecords = true;
                $memberRel->freeze( );    
            } 
            $memberOrg->freeze( );
            if ( $searchDone ) {
                $memberOrg->unfreeze( );
            }
        }
        
        if  ( ($this->_action & CRM_Core_Action::UPDATE) && $reminderDay ) {
            $renewMessage     = array();
            $returnProperties = array( 'renewal_msg_id', 'renewal_reminder_day' );
            CRM_Core_DAO::commonRetrieveAll( 'CRM_Member_DAO_MembershipType', 'id', $this->_id, $renewMessage, $returnProperties );
            if ( CRM_Utils_Array::value( 'renewal_msg_id', $renewMessage[$this->_id]) && 
                 CRM_Utils_Array::value( 'renewal_reminder_day', $renewMessage[$this->_id]) &&
                 $membershipRecords ) {
                $reminderMsg  = $this->add( 'select', 'renewal_msg_id', ts('Renewal Reminder Message'), 
                                            array('' => ts('- select -')) + $msgTemplates );
                $reminderDay->freeze( );
                $reminderMsg->freeze( );
            }
        }
               
        $this->addElement( 'submit', $this->getButtonName('refresh'), $searchBtn, array( 'class' => 'form-submit' ) );
        
        $this->addFormRule(array('CRM_Member_Form_MembershipType', 'formRule'));

        $this->assign('membershipTypeId', $this->_id);
    }
    
    /**
     * Function for validation
     *
     * @param array $params (ref.) an assoc array of name/value pairs
     *
     * @return mixed true or array of errors
     * @access public
     * @static
     */
    public function formRule( &$params ) 
    {
        require_once 'CRM/Utils/Rule.php';        
        $errors = array( );
        if ( !isset($params['_qf_MembershipType_refresh']) || !$params['_qf_MembershipType_refresh'] ) {
            if ( !$params['name'] ) {
                $errors['name'] = ts('Please enter a membership type name.');
            }
            
            if ( !CRM_Utils_Array::value('contact_check',$params) && $params['action']!= CRM_Core_Action::UPDATE ) {
                $errors['member_org'] = ts('Please select the membership organization');
            }
            
            if ( empty( $params['contribution_type_id'] ) ) {
                $errors['contribution_type_id'] = ts('Please enter a contribution type.');
            }
            
            if ( ($params['minimum_fee'] > 0 ) && !$params['contribution_type_id'] ) {
                $errors['contribution_type_id'] = ts('Please enter the contribution type.');
            }
            
            if ( empty( $params['duration_unit'] ) ) {
                $errors['duration_unit'] = ts('Please enter a duration unit.');
            }            
            
            if ( empty( $params['duration_interval'] ) and $params['duration_unit'] != 'lifetime' ) {
                $errors['duration_interval'] = ts('Please enter a duration interval.');
            }
            
            if ( empty( $params['period_type'] ) ) {
                $errors['period_type'] = ts('Please select a period type.');
            }
            
            if ( $params['period_type']   == 'fixed'  && 
                 $params['duration_unit'] == 'day' ) {
                $errors['period_type'] = ts('Period type should be Rolling when duration unit is Day');
            }
            
            $config =& CRM_Core_Config::singleton( );
            if ( ( $params['period_type']   == 'fixed' ) && 
                ( $params['duration_unit'] == 'year'  ) ) {
                $periods = array('fixed_period_start_day', 'fixed_period_rollover_day');
                foreach ( $periods as $period ) {
                    $month = $params[$period][$config->dateformatMonthVar];
                    $date  = $params[$period]['d'];
                    if ( !$month || !$date ) {
                        switch ($period) {
                        case 'fixed_period_start_day':
                            $errors[$period] = ts('Please enter a valid fixed period start day');
                            break;
                        case 'fixed_period_rollover_day':
                            $errors[$period] = ts('Please enter a valid fixed period rollover day');
                            break;
                        }
                    }
                }
            }
        }
        
        if ( $params['fixed_period_start_day'] && ! empty( $params['fixed_period_start_day']) ) {
            $params['fixed_period_start_day']['Y'] = date('Y');
            if ( ! CRM_Utils_Rule::qfDate( $params['fixed_period_start_day'] ) ){
                $errors['fixed_period_start_day'] = ts('Please enter valid Fixed Period Start Day');
            }
            
        }

        if ( $params['fixed_period_rollover_day'] && ! empty( $params['fixed_period_rollover_day']) ) {
            $params['fixed_period_rollover_day']['Y'] = date('Y');
            if ( ! CRM_Utils_Rule::qfDate( $params['fixed_period_rollover_day'] ) ){
                $errors['fixed_period_rollover_day'] = ts('Please enter valid Fixed Period Rollover Day');
            }
        }

        $renewalReminderDay = CRM_Utils_Array::value( 'renewal_reminder_day', $params );
        $renewalMsgId       = CRM_Utils_Array::value( 'renewal_msg_id', $params ); 
        if ( !( ( ($renewalReminderDay && $renewalMsgId ) ) || ( ! $renewalReminderDay &&  ! $renewalMsgId ) ) ) {

            if ( ! $renewalReminderDay ) {
                $errors['renewal_reminder_day'] = ts('Please enter renewal reminder days.');
            } elseif ( ! $renewalMsgId ) {
                $errors['renewal_msg_id']       = ts('Please select renewal message.');
            }
        }
        return empty($errors) ? true : $errors;
    }
    
    /**
     * Function to process the form
     *
     * @access public
     * @return None
     */
    public function postProcess() 
    {
        require_once 'CRM/Member/BAO/MembershipType.php';
        if($this->_action & CRM_Core_Action::DELETE) {
            $wt = CRM_Utils_Weight::delWeight('CRM_Member_DAO_MembershipType', $this->_id);
            CRM_Member_BAO_MembershipType::del($this->_id);
            CRM_Core_Session::setStatus( ts('Selected membership type has been deleted.') );
        } else { 
            $params = $ids = array( );
            $params = $this->exportValues();

            $this->set( 'searchDone', 0 );
            if ( CRM_Utils_Array::value( '_qf_MembershipType_refresh', $_POST ) ) {
                $this->search( $params );
                $this->set( 'searchDone', 1 );
                return;
            }
           
            $params['minimum_fee'] = CRM_Utils_Rule::cleanMoney( $params['minimum_fee'] );
            if ( CRM_Utils_Array::value( 'relationship_type_id', $params ) ) {
                $relationId = explode( '_', $params['relationship_type_id'] );
                $params['relationship_type_id'  ] = $relationId[0];
                $params['relationship_direction'] = $relationId[1].'_'.$relationId[2];
            } 
            if ($this->_action & CRM_Core_Action::UPDATE ) {
                $ids['membershipType'] = $this->_id;
            }
            
            if ($params['duration_unit'] == 'lifetime' and empty($params['duration_interval'])) {
                $params['duration_interval'] = 1;
            }
            
            $config =& CRM_Core_Config::singleton( );
            $periods = array('fixed_period_start_day', 'fixed_period_rollover_day');
            foreach ( $periods as $per ) {
                if ($params[$per][$config->dateformatMonthVar] && $params[$per]['d']) {
                    $mon = $params[$per][$config->dateformatMonthVar];
                    $dat = $params[$per]['d'];
                    $mon = ( $mon < 9) ? '0'.$mon : $mon; 
                    $dat = ( $dat < 9) ? '0'.$dat : $dat; 
                    $params[$per] = $mon . $dat;
                } else {
                    $params[$per] = 'null';
                }
            }
            $oldWeight = null;
            $ids['memberOfContact'] = CRM_Utils_Array::value( 'contact_check', $params );
            if ($this->_id) {
                $oldWeight = CRM_Core_DAO::getFieldValue( 'CRM_Member_DAO_MembershipType', $this->_id, 'weight', 'id' );
            }
            $params['weight'] = 
                CRM_Utils_Weight::updateOtherWeights('CRM_Member_DAO_MembershipType', $oldWeight, $params['weight']);
            
            $membershipType = CRM_Member_BAO_MembershipType::add($params, $ids);
            CRM_Core_Session::setStatus( ts('The membership type \'%1\' has been saved.', array( 1 => $membershipType->name )) );
        } 
    }

    /**
     * This function is to get the result of the search for membership organisation.
     *
     * @param  array $params  This contains elements for search criteria
     *
     * @access public
     * @return None
     *
     */
    function search(&$params) 
    {
        //max records that will be listed
        $searchValues = array();
        if ( !empty($params['member_org']) ) {
            $searchValues[] = array( 'sort_name', 'LIKE', $params['member_org'], 0, 1 );
        }
        $searchValues[] = array( 'contact_type', '=', 'organization', 0, 0 );

        // get the count of contact
        require_once 'CRM/Contact/BAO/Contact.php';
        $contactBAO  =& new CRM_Contact_BAO_Contact( );
        $query =& new CRM_Contact_BAO_Query( $searchValues );
        $searchCount = $query->searchQuery(0, 0, null, true );
        $this->set( 'searchCount', $searchCount );
        if ( $searchCount <= self::MAX_CONTACTS ) {
            // get the result of the search
            $result = $query->searchQuery(0, self::MAX_CONTACTS, null);

            $config =& CRM_Core_Config::singleton( );
            $searchRows = array( );

            while($result->fetch()) {
                $contactID = $result->contact_id;

                $searchRows[$contactID]['id'] = $contactID;
                $searchRows[$contactID]['name'] = $result->sort_name;
                $searchRows[$contactID]['city'] = $result->city;
                $searchRows[$contactID]['state'] = $result->state_province;
                $searchRows[$contactID]['email'] = $result->email;
                $searchRows[$contactID]['phone'] = $result->phone;

                $contact_type = '<img src="' . $config->resourceBase . 'i/contact_';

                $contact_type .= 'org.gif" alt="' . ts('Organization') . '" height="16" width="18" />';

                $searchRows[$contactID]['type'] = $contact_type;
            }
            $this->set( 'searchRows' , $searchRows );
        } else {
            // resetting the session variables if many records are found
            $this->set( 'searchRows' , null );
        }
    }

}


