/**
 * with_successive_milestones helper
 *
 * @param array $params
 * @param Smarty $smarty
 * @return string
 */
function smarty_function_with_successive_milestones($params, &$smarty)
{
    static $counter = 1;
    $name = array_var($params, 'name');
    if (empty($name)) {
        return new InvalidParamError('name', $name, '$name value is required', true);
    }
    // if
    $milestone = array_var($params, 'milestone');
    if (!instance_of($milestone, 'Milestone')) {
        return new InvalidParamError('milestone', $milestone, '$milestone value is expected to be an instance of Milestone class', true);
    }
    // if
    $id = array_var($params, 'id');
    if (empty($id)) {
        $id = 'with_successive_milestones_' . $counter;
        $counter++;
    }
    // if
    $value = array_var($params, 'value');
    $action = array_var($value, 'action', 'dont_move');
    $milestones = array_var($value, 'milestones');
    if (!is_array($milestones)) {
        $milestones = array();
    }
    // if
    $logged_user = $smarty->get_template_vars('logged_user');
    $successive_milestones = Milestones::findSuccessiveByMilestone($milestone, STATE_VISIBLE, $logged_user->getVisibility());
    if (!is_foreachable($successive_milestones)) {
        return '<p class="details">' . lang('This milestone does not have any successive milestones') . '</p>';
    }
    // if
    $result = "<div class=\"with_successive_milestones\">\n<div class=\"options\">\n";
    $options = array('dont_move' => lang("Don't change anything"), 'move_all' => lang('Adjust all successive milestone by the same number of days'), 'move_selected' => lang('Adjust only selected successive milestones by the same number of days'));
    foreach ($options as $k => $v) {
        $radio = radio_field($name . '[action]', $k == $action, array('value' => $k, 'id' => $id . '_' . $k));
        $label = label_tag($v, $id . '_' . $k, false, array('class' => 'inline'), '');
        $result .= '<span class="block">' . $radio . ' ' . $label . "</span>\n";
    }
    // if
    $result .= "</div>\n<div class=\"successive_milestones\">";
    foreach ($successive_milestones as $successive_milestone) {
        $input_attributes = array('name' => $name . '[milestones][]', 'id' => $id . '_milestones_' . $successive_milestone->getId(), 'type' => 'checkbox', 'value' => $successive_milestone->getId(), 'class' => 'auto');
        if (in_array($successive_milestone->getId(), $milestones)) {
            $input_attributes['checked'] = true;
        }
        // if
        $input = open_html_tag('input', $input_attributes, true);
        $label = label_tag($successive_milestone->getName(), $id . '_milestones_' . $successive_milestone->getId(), false, array('class' => 'inline'), '');
        $result .= '<span class="block">' . $input . ' ' . $label . "</span>\n";
    }
    // foreach
    $result .= "</div>\n</div>\n";
    return $result;
}
 /**
  * Reschedule selected milestone
  *
  * @param void
  * @return null
  */
 function reschedule()
 {
     if ($this->active_milestone->isNew()) {
         $this->httpError(HTTP_ERR_NOT_FOUND);
     }
     // if
     if (!$this->active_milestone->canEdit($this->logged_user)) {
         $this->httpError($this->logged_user);
     }
     // if
     $milestone_data = $this->request->post('milestone');
     if (!is_array($milestone_data)) {
         $milestone_data = array('start_on' => $this->active_milestone->getStartOn(), 'due_on' => $this->active_milestone->getDueOn(), 'reschedule_milstone_objects' => false);
     }
     // if
     $this->smarty->assign('milestone_data', $milestone_data);
     if ($this->request->isSubmitted()) {
         db_begin_work();
         $old_due_on = new DateValue($this->active_milestone->getDueOn());
         $new_start_on = new DateValue(array_var($milestone_data, 'start_on'));
         $new_due_on = new DateValue(array_var($milestone_data, 'due_on'));
         $reschedule_tasks = (bool) array_var($milestone_data, 'reschedule_milstone_objects');
         $successive_milestones = Milestones::findSuccessiveByMilestone($this->active_milestone, STATE_VISIBLE, $this->logged_user->getVisibility());
         // before we update timestamp
         $reschedule = $this->active_milestone->reschedule($new_start_on, $new_due_on, $reschedule_tasks);
         if ($reschedule && !is_error($reschedule)) {
             //if (instance_of($new_due_on, 'DateValue')){
             if ($new_due_on->getTimestamp() != $old_due_on->getTimestamp()) {
                 $with_successive = array_var($milestone_data, 'with_sucessive');
                 $to_move = null;
                 switch (array_var($with_successive, 'action')) {
                     case 'move_all':
                         $to_move = $successive_milestones;
                         break;
                     case 'move_selected':
                         $selected_milestones = array_var($with_successive, 'milestones');
                         if (is_foreachable($selected_milestones)) {
                             $to_move = Milestones::findByIds($selected_milestones, STATE_VISIBLE, $this->logged_user->getVisibility());
                         }
                         // if
                         break;
                 }
                 // switch
                 if (is_foreachable($to_move)) {
                     $diff = $new_due_on->getTimestamp() - $old_due_on->getTimestamp();
                     foreach ($to_move as $to_move_milestone) {
                         $milestone_start_on = $to_move_milestone->getStartOn();
                         $milestone_due_on = $to_move_milestone->getDueOn();
                         $new_milestone_start_on = $milestone_start_on->advance($diff, false);
                         $new_milestone_due_on = $milestone_due_on->advance($diff, false);
                         $to_move_milestone->reschedule($new_milestone_start_on, $new_milestone_due_on, $reschedule_tasks);
                     }
                     // foreach
                 }
                 // if
             }
             // if
             db_commit();
             if ($this->request->getFormat() == FORMAT_HTML) {
                 //flash_success('Milestone ":name" has been updated', array('name' => $this->active_milestone->getName()), false, true);
                 flash_success('Project ":name" has been updated', array('name' => $this->active_milestone->getName()), false, true);
                 $this->redirectToUrl($this->active_milestone->getViewUrl());
             } else {
                 $this->serveData($this->active_milestone);
             }
             // if
             //}
         } else {
             db_rollback();
             if ($this->request->getFormat() == FORMAT_HTML) {
                 $this->smarty->assign('errors', $reschedule);
             } else {
                 $this->serveData($save);
             }
             // if
         }
         // if
     }
     // if
 }