<?php
/*
 * PiAnoS (Picture Annotation System), A fingerprint examiner training tool
 * Copyright (C) 2011-2012 University of Lausanne, Switzerland
 * https://ips-labs.unil.ch/pianos
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program 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, see http://www.gnu.org/licenses/.
 */
class NIJPlugin
{
    public function __construct()
    {
        $this->_db = Application::instance()->getDB();
    }
    public function call( $event, &$data )
    {
        switch( $event )
        {
            case 'deleteUser':
                $id = ( int ) $data;
                $this->_db->query( "DELETE FROM survey_result WHERE person = " . $id . ";" );
                $this->_db->query( "DELETE FROM nij_person_data WHERE person = " . $id . ";" );
                break;
        }
    }
    public function getUserAnalysisApproach( $userid )
    {
        $res = $this->_db->query( "SELECT answer FROM survey_result WHERE survey = 1 AND person = " . ( int ) $userid . " AND question = " . ( int ) Application::get( 'analysis_approach_question_num' ) . ";" );
        if( count( $res ) != 1 )
            throw new Exception( "Database integrity error" );
        $val = ( int ) $res[ 0 ][ 'answer' ] + 1;
        if( $val != 1 && $val != 2 )
            throw new Exception( "Database integrity error" );
        return $val;
    }
    public function isMarkOfNoValue( $assignmentID )
    {
        $res = $this->_db->query( "SELECT value FROM observation WHERE assignment = " . ( int ) $assignmentID . " AND restype = (SELECT ID FROM resulttype WHERE short = 'VALIDATED') AND resstep = (SELECT ID FROM resultstep WHERE short = 'ANALYSIS') AND type = (SELECT ID FROM observationtype WHERE name = 'mark-value');" );
        if( count( $res ) != 1 )
            throw new Exception( "Database integrity error" );
        $val = ( int ) $res[ 0 ][ 'value' ];
        if( $val !== 0 && $val !== 1 && $val !== 2 )
            throw new Exception( "Database integrity error" );
        return $val === 0;
    }
    public function getCompletionCode()
    {
        $exs = $this->_db->getFolderExercises( NULL, true );
        $numDone = 0;
        foreach( $exs as $ex )
        {
            if( ( int ) $ex[ 'progress' ][ 'status' ] >= 4 )
                $numDone ++ ;
        }
        if( $numDone == count( $exs ) )
            return md5( $_SESSION[ 'user' ][ 'username' ] );
        else
            throw new Exception( "Access denied" );
    }
    private $_db;
}

require_once ( "unil/Node.php" );
class NIJ_BrowserCheckContent extends Node
{
    function __construct()
    {
    }
    function render( &$rs )
    {
        // Theme-related CSS
        $rs->setJQueryStyleSheet( Application::get( 'jqueryui_theme' ), 'theme-backend.css' );
        // Theme agnostic CSS
        $rs->getPage()->addStyleSheet( 'css/backend.css' );
        
        $this->domStart( 'div', NULL, array (), 'style="text-align:center;width:100%;"' );
        $this->domStart( 'div', NULL, array (
                'ui-widget', 
                'login_panel' 
        ), 'style="width:50%"' );
        $this->domStart( 'div', NULL, array (
                'ui-widget-header', 
                'ui-corner-top' 
        ), 'style="text-align:center;margin-bottom:0;"' );
        echo "Welcome !";
        $this->domClose();
        $this->domStart( 'div', NULL, array (
                'ui-widget-content', 
                'ui-corner-bottom' 
        ), 'style="padding:1em"' );
        echo '<p>Dear participant,</p>';
        echo '<p>Thank you for participating in this study. You will be using PiAnoS, a fingerprint examiner annotation tool. PiAnoS is entirely web-based, and runs inside your browser. </p>';
        echo '<p><strong>To make sure you get the best possible experience, we need to check that your browser is able to run PiAnoS. If the tests fail, a course of actions will be suggested.</strong></p>';
        echo '<p>We would like to thank you in advance for taking some of your precious time to help us.</p>';
        echo '<p>The project team</p>';
        $this->domClose();
        $this->domClose();
        $this->domClose();
        
        $this->domStart( 'div', NULL, array (), 'style="text-align:center;width:100%;"' );
        $this->domStart( 'div', NULL, array (
                'ui-widget', 
                'login_panel' 
        ), 'style="width:50%"' );
        $this->domStart( 'div', NULL, array (
                'ui-widget-header', 
                'ui-corner-top' 
        ), 'style="text-align:center;margin-bottom:0;"' );
        echo "Browser compatibility check";
        $this->domClose();
        $this->domStart( 'div', NULL, array (
                'ui-widget-content', 
                'ui-corner-bottom' 
        ), 'style="padding:1em"' );
        $this->domElement( 'h3', '1. Javascript:' );
        $this->domStart( 'noscript', NULL, array (
                'ui-state-error', 
                'ui-corner-all' 
        ) );
        echo 'Javascript is disabled. Please <a href="https://www.google.com/search?q=enable+javascript">enable it</a> and refresh this page.';
        $this->domClose();
        $this->domElement( 'div', '', 'check_javascript', array (
                'ui-state-highlight', 
                'ui-corner-all' 
        ) );
        $this->domElement( 'h3', '2. Is browser compatible ?' );
        $this->domElement( 'noscript', 'N/A', NULL, array (
                'ui-state-error', 
                'ui-corner-all' 
        ) );
        $this->domElement( 'div', '', 'check_version', array (
                'ui-corner-all' 
        ) );
        $this->domClose();
        $this->domClose();
        $this->domClose();
        
        $this->domStart( 'div', 'tests_ok', array (), 'style="text-align:center;width:100%;display:none"' );
        $this->domStart( 'div', NULL, array (
                'ui-widget', 
                'login_panel' 
        ), 'style="width:50%"' );
        $this->domStart( 'div', NULL, array (
                'ui-widget-header', 
                'ui-corner-top' 
        ), 'style="text-align:center;margin-bottom:0;"' );
        echo 'Next step';
        $this->domClose();
        $this->domStart( 'div', NULL, array (
                'ui-widget-content', 
                'ui-corner-bottom' 
        ), 'style="padding:1em"' );
        $this->domElement( 'p', 'All tests passed, you are ready to go !' );
        $this->domStart( 'p' );
        echo '<strong>Should you encounter problems after this page, please switch to <a href="http://www.mozilla.org/en-US/firefox/new/">Firefox</a> 4+ before giving up. A version that requires no installer and no administrative rights exists: <a href="http://portableapps.com/apps/internet/firefox_portable">Firefox Portable</a>.</strong>';
        $this->domClose();
        $this->domElement( 'a', 'Start the study !', 'button_start', array (), 'href="?skip=1"' );
        $this->domClose();
        $this->domClose();
        $this->domClose();
        
        $this->domStart( 'div', 'tests_failed', array (), 'style="text-align:center;width:100%;display:none"' );
        $this->domStart( 'div', NULL, array (
                'ui-widget', 
                'login_panel' 
        ), 'style="width:50%"' );
        $this->domStart( 'div', NULL, array (
                'ui-widget-header', 
                'ui-corner-top' 
        ), 'style="text-align:center;margin-bottom:0;"' );
        echo 'Next step';
        $this->domClose();
        $this->domStart( 'div', NULL, array (
                'ui-widget-content', 
                'ui-corner-bottom' 
        ), 'style="padding:1em"' );
        $this->domStart( 'p' );
        echo '<strong>We are sorry, some tests failed !</strong>';
        $this->domClose();
        $this->domElement( 'p', 'Unfortunately, your browser does not seem to be able to run PiAnoS. You may at your option:' );
        $this->domStart( 'ul' );
        echo '<li><strong>Recommended :</strong> Use <a href="http://portableapps.com/apps/internet/firefox_portable">Firefox Portable</a>, a version of Mozilla Firefox that requires no installer and no administrative rights.</li>';
        echo '<li style="margin-top:0.5em">Install <a href="http://www.mozilla.org/en-US/firefox/new/">Mozilla Firefox</a><br /><em>Note: this requires administrative rights on your system. If this is a problem, please see the previous option.</em></li>';
        echo '<li style="margin-top:0.5em">Prefer <a href="https://www.google.com/chrome">Google Chrome</a>, <a href="http://www.apple.com/safari/download/">Apple Safari</a>, <a href="http://www.opera.com/">Opera</a>, or any browser that supports recent web standards.<br /><em>Note: same restrictions as previous point apply.</em></li>';
        echo '<li style="margin-top:0.5em">Ignore this message and <a href="?skip=2">continue</a> at your own risks. If you decide to do so, just keep the "Portable Firefox" keywords in mind for future googling :)</li>';
        $this->domClose();
        $this->domClose();
        $this->domClose();
        $this->domClose();
        
        $this->domStartJS();
        echo "
		$(document).ready(function() {
			var failed = false;
			$('#check_javascript').addClass('ui-state-default').css('color','#2CA02C').css('border-color','#2CA02C').html('Enabled !');
			$('#check_version').html('');
			var major = parseInt($.browser.version);
			if (('msie' in $.browser && major < 9) || ('mozilla' in $.browser && major < 4))
			{
				$('#check_version').addClass('ui-state-error').append('No !');
				failed = true;
			}
			else
			{
				$('#check_version').addClass('ui-state-default').css('color','#2CA02C').css('border-color','#2CA02C').append('Yes !');
			}
			
			if (failed)
			{
				$('#tests_failed').show();
			}
			else
			{
				$('#tests_ok').show();
				$('#button_start').button();
			}
		});
		";
        $this->domClose();
    }
}
class NIJ_SurveyContent extends Node
{
    function __construct( $survey )
    {
        $this->survey = $survey;
    }
    function render( &$rs )
    {
        // Theme-related CSS
        $rs->setJQueryStyleSheet( Application::get( 'jqueryui_theme' ), 'theme-backend.css' );
        // Theme agnostic CSS
        $rs->getPage()->addStyleSheet( 'css/backend.css' );
        
        $rs->getPage()->addStyleSheet( 'css/survey.css' );
        $this->survey->display();
    }
    private $survey;
}
class NIJ_IntroDriver extends ContentDriver
{
    public function accept()
    {
        if( $_SESSION[ 'user' ][ 'isadmin' ] )
            return false;
        
        $maxStep = 0;
        if( Application::get( 'initial_browser_check' ) )
             ++ $maxStep;
        if( Application::get( 'initial_survey' ) )
             ++ $maxStep;
        
        if( ! isset( $_SESSION[ 'user' ][ 'intro_step' ] ) )
        {
            $res = Application::instance()->getDB()->query( "SELECT getUserIntroStep(" . ( int ) $_SESSION[ 'user' ][ 'id' ] . ");" );
            $step = ( int ) $res[ 0 ][ 'getuserintrostep' ];
            if( $step < 0 || $step > 2 )
                $step = 0;
            $_SESSION[ 'user' ][ 'intro_step' ] = $step;
        }
        
        if( $_SESSION[ 'user' ][ 'intro_step' ] == $maxStep )
        {
            // Automatic insertion of the browser check if needed
            $res = Application::instance()->getDB()->query( "SELECT count(*) FROM nij_person_data WHERE person = " . ( int ) $_SESSION[ 'user' ][ 'id' ] . " AND key = E'" . pg_escape_string( 'browser_check' ) . "';" );
            if( ( int ) $res[ 0 ][ 'count' ] !== 1 )
            {
                Application::instance()->getDB()->query( "INSERT INTO nij_person_data(person,key,value) VALUES (" . ( int ) $_SESSION[ 'user' ][ 'id' ] . ",E'" . pg_escape_string( 'browser_check' ) . "',E'2');" );
            }
            
            // Automatic insertion of analysis conclusion approach #2 for users without the survey (only if required)
            $res = Application::instance()->getDB()->query( "SELECT count(*) FROM survey_result WHERE survey = 1 AND person = " . ( int ) $_SESSION[ 'user' ][ 'id' ] . " AND question = " . ( int ) Application::get( 'analysis_approach_question_num' ) . ";" );
            if( ( int ) $res[ 0 ][ 'count' ] !== 1 )
            {
                Application::instance()->getDB()->query( "INSERT INTO survey_result(survey,person,question,answer) VALUES (1," . ( int ) $_SESSION[ 'user' ][ 'id' ] . "," . ( int ) Application::get( 'analysis_approach_question_num' ) . ",1);" );
            }
            
            $_SESSION[ 'user' ][ 'intro_step' ] += 1;
        }
        
        return $_SESSION[ 'user' ][ 'intro_step' ] < $maxStep;
    }
    protected function doHandleRequest()
    {
        if( ! isset( $_SESSION[ 'user' ] ) || ! isset( $_SESSION[ 'user' ][ 'intro_step' ] ) )
            throw new Exception( "Assertion failed" );
        
        if( $_SESSION[ 'user' ][ 'intro_step' ] == 0 )
        {
            if( isset( $_GET[ 'skip' ] ) && strlen( $_GET[ 'skip' ] ) )
            {
                Application::instance()->getDB()->query( "INSERT INTO nij_person_data(person,key,value) VALUES (" . ( int ) $_SESSION[ 'user' ][ 'id' ] . ",E'" . pg_escape_string( 'browser_check' ) . "',E'" . pg_escape_string( $_GET[ 'skip' ][ 0 ] ) . "');" );
                header( "Location: ?" );
                exit();
            }
            
            $content = new NIJ_BrowserCheckContent();
            $this->printHtml( $content );
        } elseif( $_SESSION[ 'user' ][ 'intro_step' ] == 1 )
        {
            $db = Application::instance()->getDB();
            
            require_once ( "survey/survey.php" );
            
            $res = $db->query( "SELECT definition FROM survey ORDER BY ID ASC LIMIT 1;" );
            if( count( $res ) != 1 )
                throw new Exception( "Assertion failed" );
            
            $survey = new Survey( $res[ 0 ][ 'definition' ], true, true );
            
            if( $survey->checkPost() )
            {
                $db->beginTransaction();
                $res = $db->query( "SELECT ID FROM survey ORDER BY ID ASC LIMIT 1;" );
                if( count( $res ) != 1 )
                    throw new Exception( "Assertion failed" );
                $sid = ( int ) $res[ 0 ][ 'id' ];
                $db->query( "DELETE FROM survey_result WHERE survey = " . $sid . " AND person = " . ( int ) $_SESSION[ 'user' ][ 'id' ] . ";" );
                foreach( $survey->getAnswers() as $id => $ans )
                {
                    $db->query( "INSERT INTO survey_result(survey,person,question,answer,comment) VALUES (" . $sid . "," . ( int ) $_SESSION[ 'user' ][ 'id' ] . "," . ( int ) $id . "," . ( int ) $ans[ 'value' ] . ",E'" . pg_escape_string( $ans[ 'comment' ] ) . "');" );
                }
                $db->commitTransaction();
                $_SESSION[ 'user' ][ 'intro_step' ] = 2;
                header( "Location: ?" );
                exit();
            } else
            {
                $content = new NIJ_SurveyContent( $survey );
                $this->printHtml( $content );
            }
        } else
            throw new Exception( "Assertion failed" );
    }
}
