<?php
function task_list($pid, $status, $order) {
    global $conn, $appconf, $smarty;
    $tasks = array();
    // print the nice indented list
    $sql = "SELECT * FROM mgw_projects_tasks WHERE parent_id = 0 AND project_id='$pid' ORDER BY $order";
    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    while($task = $res->FetchRow()) {
	$sql2 = "SELECT ".$conn->Concat('lastname',"', '",'firstname')." AS uname FROM mgw_users WHERE id='".$task['assignee']."'";
	if(($user = $conn->GetRow($sql2))===false) exit(showSQLerror($sql2, $conn->ErrorMsg(), __LINE__, __FILE__));
	$task['uname'] = $user['uname'];
	if (get_decendents($task['task_id'],$status) || $task['status']==$status) {	
	    if ($task['status'] == "$status") {
		if ($status==1) {
		    if (get_children($task['task_id'],1)) {
			$task['action']['url'][0] = "#";
			$task['action']['img'][0] = "d-off.gif";
			$task['action']['url'][1] = "#";
			$task['action']['img'][1] = "f-off.gif";
		    } else {
			$task['action']['url'][0] = "index.php?obj=task&amp;view=delete&amp;tid=$task[task_id]&amp;pid=$pid&amp;".SID;
			$task['action']['img'][0] = "d-on.gif";
			$task['action']['url'][1] = "index.php?obj=task&amp;action=finish&amp;tid=$task[task_id]&amp;pid=$pid&amp;".SID;
			$task['action']['img'][1] = "f-on.gif";
		    }
		} else {
		    if (get_children($task['task_id'],0)) {
			$task['action']['url'][0] = "#";
			$task['action']['img'][0] = "d-off.gif";
			$task['action']['url'][1] = "index.php?obj=task&amp;action=reset&amp;tid=$task[task_id]&pid=$pid&amp;".SID;
			$task['action']['img'][1] = "r-on.gif";
		    } else {
			$task['action']['url'][0] = "index.php?obj=task&amp;view=delete&amp;tid=$task[task_id]&amp;pid=$pid&amp;".SID;
			$task['action']['img'][0] = "d-on.gif";
			$task['action']['url'][1] = "index.php?obj=task&amp;action=reset&amp;tid=$task[task_id]&amp;pid=$pid&amp;".SID;
			$task['action']['img'][1] = "r-on.gif";
		    }				
		}	
	    } else {
		$task['class'] = 'tab';
		$task['action']['url'][0] = "#";
		$task['action']['img'][0] = "d-off.gif";
		$task['action']['url'][1] = "#";
		$task['action']['img'][1] = "f-off.gif";
	    }
	    $tasks[] = $task;
	}
	$tasks = print_tree($task['task_id'], 0, $status, $tasks);
    }
    $smarty->assign('tstatus', $status);
    $smarty->assign('totalhours', ($status == 1) ? hours_todo($pid) : hours_done($pid));
    $smarty->assign('totalusedhours', ($status == 1) ? usedhours_todo($pid) : usedhours_done($pid));
    $smarty->assign('tasks', $tasks);
    return $smarty->fetch('projects_tasklist.tpl');
}

function print_tree($task_id, $count, $status, $tasks) {
    global $conn, $appconf;

    $count++;
    $result = get_children($task_id, 2);
    for ($x=0; $x < sizeof($result); $x++) {
	$task=get_task_info($result[$x]);
	$task['indent'] = $count * 10;
	$concat = $conn->Concat('lastname',"', '",'firstname');
	$sql2 = "SELECT $concat AS uname FROM mgw_users WHERE id='".$task['assignee']."'";
	if(($user = $conn->GetRow($sql2))===false) exit(showSQLerror($sql2, $conn->ErrorMsg(), __LINE__, __FILE__));
	$task['uname'] = $user['uname'];
	if ($task['status']==$status || get_decendents($task['task_id'],$status)) {
	    if ($task['status'] == $status) {
		if ($status==1) {
		    if (get_children($task['task_id'],1)) {
			$task['action']['url'][0] = "#";
			$task['action']['img'][0] = "/d-off.gif";
			$task['action']['url'][1] = "#";
			$task['action']['img'][1] = "f-off.gif";
		    } else {
			$task['action']['url'][0] = "index.php?obj=task&amp;view=delete&amp;tid=$task[task_id]&amp;pid=$task[project_id]&amp;".SID;
			$task['action']['img'][0] = "d-on.gif";
			$task['action']['url'][1] = "index.php?obj=task&amp;action=finish&amp;tid=$task[task_id]&amp;pid=$task[project_id]&amp;".SID;
			$task['action']['img'][1] = "f-on.gif";
		    }
		} else {
		    if (get_children($task['task_id'],0)) {
			$task['action']['url'][0] = "#";
			$task['action']['img'][0] = "d-off.gif";
			$task['action']['url'][1] = "index.php?obj=task&amp;action=reset&amp;tid=$task[task_id]&amp;pid=$task[project_id]&amp;".SID;
			$task['action']['img'][1] = "r-on.gif";
		    } else {
			$task['action']['url'][0] = "index.php?obj=task&amp;view=delete&amp;tid=$task[task_id]&amp;pid=$task[project_id]&amp;".SID;
			$task['action']['img'][0] = "d-on.gif";
			$task['action']['url'][1] = "index.php?obj=task&amp;action=reset&amp;tid=$task[task_id]&amp;pid=$task[project_id]&amp;".SID;
			$task['action']['img'][1] = "r-on.gif";
		    }				
		}	
	    } else {
		$task['class'] = 'tab';
		$task['action']['url'][0] = "#";
		$task['action']['img'][0] = "d-off.gif";
		$task['action']['url'][1] = "#";
		$task['action']['img'][1] = "f-off.gif";
	    }
	    $tasks[] = $task;
	    $tasks = print_tree($result[$x], $count, $status, $tasks);
	}
    }
    return $tasks;
}

function is_toplevel($task_id) {
    global $conn;

    $sql = "SELECT parent_id FROM mgw_projects_tasks WHERE task_id='$task_id'";
    if(($parent = $conn->GetRow($sql))===false) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    return ($parent['parent_id']==0) ? true : false;
}

function get_children($task_id, $status) {
    global $conn;

    // returns the task_id's of all child tasks that are status=$status
    $children = array();
    $count = 0;
    if (($status == 0) || ($status == 1)) {
	$sql = "SELECT task_id FROM mgw_projects_tasks WHERE parent_id='$task_id' AND status='$status'";
    } else {
	$sql = "SELECT task_id FROM mgw_projects_tasks WHERE parent_id='$task_id'";
    }
    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    while($row = $res->FetchRow()) {
	$children[] = $row["task_id"];
    }

    return $children;
}

function get_decendents($task_id, $status, $count = 0, $decendents=array()) {
    $result = get_children($task_id, 2);
    for ($x=0; $x<sizeof($result); $x++) {
	$task=get_task_info($result[$x]);
	if (get_children($task['task_id'], $status) || $status == $task['status']) {
	    $decendents[$x] = $result[$x];
	}
	get_decendents($result[$x], $count, $status, $decendents);
    }
    return $decendents;
}

function get_task_info($task_id) {
    global $conn;

    // returns the data concerning a task
    $sql = "SELECT * FROM mgw_projects_tasks WHERE task_id='$task_id'";
    if(($row = $conn->GetRow($sql))===false) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    return $row;
}

//Create a task dropdown box
// Allow for the dropdown to be parent_id or any other field
function task_dropdown($pid, $tid=0, $field="parent_id") {
    global $conn;

    // return the nice indented HTML select list
    $rstr = '<select name=' . $field . ' size="1">';
    if($tid !=0 ){
    // Do not allow a milestone to become a parent 
    $nomilestone = ($field == "parent_id" ? " AND a.milestone=0 " : " ");
	$sql = "SELECT a.title,a.task_id FROM mgw_projects_tasks a, mgw_projects_tasks b WHERE a.task_id=b." . $field . " AND b.task_id=$tid " . $nomilestone ;
	$rstr .= "\n<!-- $sql -->\n";
	if(!($row = $conn->GetRow($sql))===false){
	    $rstr .= '<option value="'.$row['task_id'].'" selected="selected">'.$row['title'].'</option>';
	    $rstr .= '<option value="0">-------------------------------------</option>';
	}
	$rstr .= '<option value="0">'.Lang::getLanguageString('toplevel').'</option>';
	$rstr .= '<option value="0">-------------------------------------</option>';
    }
    else{
	$rstr .= '<option value="0" selected="selected">'.Lang::getLanguageString('toplevel').'</option>';
	$rstr .= '<option value="0">-------------------------------------</option>';
    }
    // Do not allow a milestone to become a parent 
    $nomilestone = ($field == "parent_id" ? " AND milestone=0 " : " ");
    $sql = "SELECT task_id,title FROM mgw_projects_tasks WHERE parent_id=0 AND project_id='$pid'" . $nomilestone;
    $rstr .= "\n<!-- $sql -->\n";
    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    while($task = $res->FetchRow()) {
	$rstr .= "<option value=\"{$task['task_id']}\">{$task['title']}</option>\n";
	$rstr = get_task_dropdown($task['task_id'], 0, $rstr, $field);
    }
    $rstr .= '</select>';
    return $rstr;
}

function get_task_dropdown($task_id, $count, $rstr, $field="parent_id") {
    $count++;
    $indent=$count*3;
    $spacing="";
    for ($x=0; $x<$indent; $x++)
	$spacing.="&nbsp;";

    $result = get_children($task_id, 2);
    for ($x=0; $x<sizeof($result); $x++) {
	$task=get_task_info($result[$x]);
	// Do not allow a milestone to become a parent 
	$rstr .= ( ($field == "parent_id") && $task['milestone']=='1'  ? "" : "<option value=\"{$task['task_id']}\">$spacing {$task['title']}</option>");
	$rstr = get_task_dropdown($result[$x], $count, $rstr);
    }
    return $rstr;
}

//=================================================
// Get Number of Tasks Per Project
// *Added by Vikor Reign
//=================================================
function getNumTasks($pid){
    global $conn;

    $sql = "SELECT project_id, status FROM mgw_projects_tasks WHERE project_id=$pid";

    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__,__FILE__));
    $active_counter = 0;
    $finished_counter = 0;
    while($row = $res->FetchRow()) {
	if ($row["status"] == "1") {
	    $active_counter++;
	}
	if ($row["status"] == "0") {
	    $finished_counter++;
	}
    }

    $numarray = array("active" =>
		      $active_counter, "finished" => $finished_counter); //

    return $numarray;
}

// =================================================
//	              Graph Tasks
// =================================================
function projectGraphTasks(&$graph, $parent, &$o, &$bar){
    global $conn;

    // First off get all the tasks with Parent_ID of $parent)
    $sql = "SELECT a.task_id, a.milestone, a.constrain_id, a.title, a.startdate, a.targetdate, a.hours, a.usedhours, a.parent_id, b.lastname AS assignee FROM mgw_projects_tasks a LEFT JOIN mgw_users b ON a.assignee=b.id WHERE project_id=" . (int)$_GET['pid'] . " AND parent_id=" . $parent . " ORDER BY startdate";
    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));

    while($row = $res->FetchRow()){

        // The bars are now in an array,
        //    with the key being their place on the graph
        //    This allows us to backreference bars for
        //    constraints and such.

        $count = count($o);

        // If the item is a Milestone
        if ($row["milestone"]== '1') {
            $bar[$count] = new MileStone ($count, $row["title"],$row["startdate"]);
            $bar[$count]->caption->Set($row['assignee']);
            $bar[$count]->caption->SetFont(FF_FONT1, FF_BOLD);
            $bar[$count]->SetCSIMTarget("index.php?obj=task&view=edit&amp;tid=".$row['task_id']."&amp;".SID);
            $bar[$count]->SetCSIMAlt(Lang::getLanguageString('edit'));
            $bar[$count]->title->SetColor("black");
            $bar[$count]->title->SetFont(FF_FONT1, FF_BOLD);
            // For some reason this screws things up??? It becomes /modules/projects/Array
            //$bar[$count]->title->SetCSIMAlt(Lang::getLanguageString('edit'));
            //$bar[$count]->title->SetCSIMTarget("index.php?obj=task&view=edit&amp;tid=".$row['task_id']."amp;".SID);
                      
        } else {

            $bar[$count] = new GanttBar($count,$row["title"],$row["startdate"],$row["targetdate"]);
            $color = ($conn->Unixdate($row["targetdate"]) > time()) ? 'green' : 'red';
            if(isset($row['status']) && $row['status'] == '0') $color = 'gray';
            $bar[$count]->caption->Set($row['assignee']);
            $bar[$count]->SetPattern(GANTT_SOLID, $color);
            if($row['usedhours'] > 0)
            $bar[$count]->progress->Set(min((1/($row['hours']/$row['usedhours'])),1));
            $bar[$count]->SetCSIMTarget("index.php?obj=task&view=edit&amp;tid=".$row['task_id']."&amp;".SID);
            $bar[$count]->title->SetCSIMTarget("index.php?obj=task&view=edit&amp;tid=".$row['task_id']."&amp;".SID);
            $bar[$count]->SetCSIMAlt(Lang::getLanguageString('edit'));
            $bar[$count]->title->SetCSIMAlt(Lang::getLanguageString('edit'));

            // If it has subtasks then make it look different
            $tempsql = "SELECT task_id, project_id, parent_id FROM mgw_projects_tasks WHERE project_id=" . (int)$_GET['pid'] . " AND parent_id=" . $row["task_id"];
            if(($temprow = $conn->GetRow($tempsql))===false) exit(showSQLerror($tempsql, $conn->ErrorMsg(), __LINE__, __FILE__));
            if(count($temprow)){
                $bar[$count]->leftMark->SetType(MARK_LEFTTRIANGLE);
                $bar[$count]->leftMark->Show();
                $bar[$count]->leftMark->SetWidth(8);
                $bar[$count]->leftMark->SetColor('black');
                $bar[$count]->leftMark->SetFillColor('black');
                $bar[$count]->rightMark->SetType(MARK_RIGHTTRIANGLE);
                $bar[$count]->rightMark->Show();
                $bar[$count]->rightMark->SetWidth(8);
                $bar[$count]->rightMark->SetColor('black');
                $bar[$count]->rightMark->SetFillColor('black');
            }
        }
        $graph->Add($bar[$count]);
        $o[] = (int)$row['task_id'] ;

        // Be recurrsive
        if(count($temprow)){
            projectGraphTasks($graph,$row['task_id'],$o,$bar);
        }
    }
}

function hours_todo($id) {
    // input project id
    // returns the ammount of hours left todo on a project
    global $conn;

    $sql = "SELECT SUM(hours) AS total FROM mgw_projects_tasks WHERE project_id='".(int)$id."' AND status='1'";
    if(($r = $conn->GetOne($sql))===false) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    return $r;
}

function usedhours_todo($id) {
    // input project id
    // returns the amount of used hours done on a project
    global $conn;

    $sql = "SELECT SUM(usedhours) AS usedtotal FROM mgw_projects_tasks WHERE project_id='".(int)$id."' AND status='1'";
    if(($r = $conn->GetOne($sql))===false) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    return $r;			
}

function hours_done($id) {
    // input project id
    // returns the ammount of hours done on a project
    global $conn;

    $sql = "SELECT SUM(hours) AS total FROM mgw_projects_tasks WHERE project_id='".(int)$id."' AND status='0'";
    if(($r = $conn->GetOne($sql))===false) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    return $r;			
}

function usedhours_done($id) {
    // input project id
    // returns the amount of used hours done on a project
    global $conn;

    $sql = "SELECT SUM(usedhours) AS usedtotal FROM mgw_projects_tasks WHERE project_id='".(int)$id."' AND status='0'";
    if(($r = $conn->GetOne($sql))===false) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    return $r;
}

function percentTimeComplete($id) {
    global $conn;

    $sql = "SELECT startdate, targetdate FROM mgw_projects WHERE project_id = ".(int)$id;
    if(!$res = $conn->Execute($sql)) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    $row = $res->FetchRow();
    $elapsed = time() - $conn->UnixDate($row["startdate"]);
    $total = $conn->UnixDate($row["targetdate"]) - $conn->UnixDate($row["startdate"]);
    if ($total == 0) {
	return 100;
    } 
    else {
	if ((100 * $elapsed / $total) == 0) {
	    return 0;
	}
	else {
	    return sprintf("%02d", 100 * $elapsed / $total);
	}
    }
}

function percentcomplete($id) {
    global $conn;
    // This function takes a project id and and compares the todo hours
    // to the finished hours to make a percent done
    
    /*
     * For a proper calculation of Percent-to-complete:
     *  For open tasks, use the usedhours if more than the planned hours
     *  to calculate todo.
     *  Percentage for closed tasks is always 100
     * Use this for percentage calculation.
     * OvE, 20050809
     */

    $Qopenpl  = 'SELECT SUM(hours) as openpl '
              . 'FROM   mgw_projects_tasks '
              . 'WHERE  project_id=' . (int)$id . ' '
              . 'AND    status=1 '
              . 'AND    usedhours <= hours';
    $Qopenot  = 'SELECT SUM(usedhours) as openot '
              . 'FROM   mgw_projects_tasks '
              . 'WHERE  project_id=' . (int)$id . ' '
              . 'AND    status=1 '
              . 'AND    usedhours > hours';
    $Qopendn  = 'SELECT SUM(usedhours) as opendn '
              . 'FROM   mgw_projects_tasks '
              . 'WHERE  project_id=' . (int)$id . ' '
              . 'AND    status=1 ';
    $Qclospl  = 'SELECT SUM(hours) as clospl '
              . 'FROM   mgw_projects_tasks '
              . 'WHERE  project_id=' . (int)$id . ' '
              . 'AND    status=0';

   // Open tasks
    $Qopen_planned    = $conn->GetOne($Qopenpl); // On schedule
    $Qopen_overtime   = $conn->GetOne($Qopenot); // Used more than planned so far
    $Qopen_done       = $conn->GetOne($Qopendn); // Time spent
    // Closed tasks
    $Qclosed_planned  = $conn->GetOne($Qclospl); // On schedule
    $Qclosed_done     = $Qclosed_planned;        // Ignore overtime

    $todo = $Qopen_planned + $Qopen_overtime + $Qclosed_planned;
    $done = $Qopen_done + $Qclosed_done;

    if (($Qopen_planned + $Qopen_overtime) == 0) {
	return 100; // No open tasks; done!
    }
    elseif ($done > 0) {
	$PercDone = (($done / $todo) * 100);
	if ($PercDone >= 100) {
		return 95; // Used more than planned but not yet done
	}
	else {
		return sprintf("%2d", $PercDone);
	}
    }
    else {
	return 0;
    }
}

function draw_time_and_progress_bars($id) {
    global $smarty;
    $timedone = percentTimeComplete($id);
    $wpercent = percentcomplete($id);

    $safe_td = max(0, min(100, $timedone));
    if (isset($completed) && $completed) { $safe_td = min(100, $safe_td); }
    if ((isset($completed) && $completed) || $safe_td < $wpercent) {
	// project complete or within schedule
	$colour = "green";
    } elseif ($timedone < 100) {
	// within deadline but behind schedule
	$colour = "yellow";
    } else {
	// project over deadline
	$colour = "red";
    }
    if ($timedone <= 0) {
	$timedone=Lang::getLanguageString('scheduled');
    } elseif ($timedone >= 100) {
	$timedone="<strong>".Lang::getLanguageString('overdue')."</strong>";
    } else {
	$timedone="$timedone%&nbsp;".Lang::getLanguageString('time');
    }
    if ($wpercent <= 0) {
	$workdone=Lang::getLanguageString('notstarted');
    } elseif ($wpercent >= 100) {
	$workdone="<strong>".Lang::getLanguageString('complete')."</strong>";
    } else {
	$workdone="$wpercent%&nbsp;".Lang::getLanguageString('work');
    }

    $percent = max(0, min(100, $safe_td));
    $l_colour = ($percent == 0   ? "grey" : $colour);
    $r_colour = ($percent == 100 ? $colour : "grey");
    // This is a hack to avoid bad browser behaviour from using <img width=0>
    if ($percent == 0  ) { $percent = 1; }
    if ($percent == 100) { $percent = 99; }
    $smarty->assign("tpercent", $percent);
    $smarty->assign("tl_colour",$l_colour);
    $smarty->assign("tr_colour",$r_colour);

    $percent = max(0, min(100, $wpercent));
    $l_colour = ($percent == 0   ? "grey" : "green");
    $r_colour = ($percent == 100 ? "green" : "grey");
    // This is a hack to avoid bad browser behaviour from using <img width=0>
    if ($percent == 0  ) { $percent = 1; }
    if ($percent == 100) { $percent = 99; }
    $smarty->assign("wpercent", $percent);
    $smarty->assign("wl_colour",$l_colour);
    $smarty->assign("wr_colour",$r_colour);

    $smarty->assign("timedone",$timedone);
    $smarty->assign("workdone",$workdone);
  
    return $smarty->fetch("projects_tp_bar.tpl");
}


function projectCalcParentHours($tid){
    global $conn;

    // Does this task have children
    $result = get_children($tid, 2);

    // If so then go to town
    if (sizeof($result)) {
        // For each child (if any)
        for ($x=0; $x<sizeof($result); $x++) {

            // If sub children then be recursive
            if (get_children($result[$x], 2)) {
                projectCalcParentHours($result[$x]);

            }


        }

        // Total hours of children
        $sql = "SELECT SUM(hours) AS total FROM mgw_projects_tasks WHERE parent_id='".(int)$tid."'";
        if(($total_hours = $conn->GetOne($sql))===false) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
        // Total hours of children DONE
        $sql = "SELECT SUM(hours) AS total FROM mgw_projects_tasks WHERE parent_id='".(int)$tid."' AND status=0";;
        if(($total_donehours = $conn->GetOne($sql))===false) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
        // Total used hours of children not done
        $sql = "SELECT SUM(usedhours) AS total FROM mgw_projects_tasks WHERE parent_id='".(int)$tid."' AND status=1";;
        if(($total_usedhours = $conn->GetOne($sql))===false) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));

        $total_completehours = $total_donehours + $total_usedhours;

        // Perform the UPDATE
        $sql = "UPDATE mgw_projects_tasks SET hours=$total_hours, usedhours=$total_completehours WHERE task_id='".(int)$tid."'";
        if(!$conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
    }
}



?>
