# This patch file was generated by NetBeans IDE
# This patch can be applied using context Tools: Apply Diff Patch action on respective folder.
# It uses platform neutral UTF-8 encoding.
# Above lines and this line are ignored by the patching process.
Index: moodle/course/modedit.php
--- moodle/course/modedit.php Base (1.34.2.12)
+++ moodle/course/modedit.php Locally Modified (Based On 1.34.2.12)
@@ -254,6 +254,16 @@
                 error($returnfromfunc, "view.php?id=$course->id");
             }
 
+//---------------------------------------------For OMR Quiz,--------------------------------------
+			if($fromform->quiztype=='omr'){
+            	$omrdata=new object();
+            	$omrdata->quizid=$fromform->instance;
+            	if(!insert_record('omrquiz', $omrdata, $returnid=false, $primarykey='id')){
+            		error("could not insert omr data in table omr quiz");
+            	}
+			} 
+//-----------------------------------------author@ Harmeet Saini----------------------------------            
+            
             set_coursemodule_visible($fromform->coursemodule, $fromform->visible);
             set_coursemodule_groupmode($fromform->coursemodule, $fromform->groupmode);
             set_coursemodule_groupingid($fromform->coursemodule, $fromform->groupingid);
@@ -291,6 +301,16 @@
 
             $fromform->instance = $returnfromfunc;
 
+//---------------------------------------------------For OMR Quiz,------------------------------------------------
+	    if($fromform->quiztype=='omr'){
+            	$omrdata=new object();
+            	$omrdata->quizid=$fromform->instance;
+            	if(!insert_record('omrquiz', $omrdata, $returnid=false, $primarykey='id')){
+            		error("could not insert omr data in table omr quiz");
+            	}
+	    }
+//----------------------------------------------author@ Harmeet Saini---------------------------------------------            
+
             // course_modules and course_sections each contain a reference
             // to each other, so we have to update one of them twice.
 
Index: moodle/lang/en_utf8/help/quiz/omranswers.html
--- moodle/lang/en_utf8/help/quiz/omranswers.html No Base Revision
+++ moodle/lang/en_utf8/help/quiz/omranswers.html Locally New
@@ -0,0 +1,65 @@
+<h1>Uploading and Correcting the Answer Sheet Data:</h1>
+<a href='#top'></a>
+<span>
+<b>Content:</b><ul>
+<li><a href='#structure&content_of_scanned_omr_answer_sheet'>Structure & Content</a></li>
+<li><a href='#Uploading_scanned_omr_answer_sheet'>Uploading Scanned File</a></li>
+<li><a href='#Retrieving_earlier_upload_answer_data'>Retrieving Earlier Upload Answer Data</a></li>
+</ul>
+</span>
+
+<h2 id='structure&content_of_scanned_omr_answer_sheet'>Structure and Contents of scanned OMR answer sheet data file:</h2>
+<ol type='a'><li><b>Structure of the scanned OMR answers file</b><br/>
+<pre>   rollno    name     variant no    answer string    </pre>
+<p><b>NOTE: </b>Position of parameter can change. </p>
+
+<li><b>Sample contents of the scanned OMR answers file</b>
+<table cellpadding=8 cellspacing=5 border=1>
+<thead><th>rollno</th><th>name</th><th>variant no + answer string</th></thead>
+<tbody>
+<tr><td>0017</td><td>ABHIRAMI KANNAN IYER</td><td> 0901BDCABABBDDABCBB</td></tr>
+<tr><td>0018</td><td>ABHISHEK CHOUDHARY</td><td> 0901BACBBDBAAADBCBA</td></tr>
+<tr><td>002</td><td>ABHISHEK JAYANT KESKAR</td><td>0900AB CADBBCB DCD</td></tr>
+<tr><td>002</td><td>ABHISHEK SANJAY GULDHE</td><td>0901BCABBDABACDCCDA</td></tR>
+<tr><td>0022</td><td>ADITEE UTTAM MANE</td><td> 0900BDCABAABACDBCDA</td></tr>
+</tbody></table>
+</li>
+</ol>
+<a id='top' href=''><font size='3' color='blue'>[TOP]</font></a>
+
+<h2 id='Uploading_scanned_omr_answer_sheet'>Uploading scanned OMR answer sheet data file:</h2>
+<ol>
+<li>Click on the “omr” tab then click on answers tab. Now an upload form will appear on the screen.</li>
+<li>Click on “browse” under “import from file upload” section and click “upload this file” to upload the scanned OMR answers file present on your file system<br/><center>OR</center><br/>
+Click on “choose or upload a file” under “import from file already in course files..” section and click “import from this file” to import the scanned OMR answers file that is already present in files area of Moodle.<br/></li>
+</ol>
+Answer files uploaded earlier can also be uploaded again.
+<br/>Refer to section <a href='#Retrieving_earlier_upload_answer_data'>Retrieving earlier uploaded answer data</a><br/>
+<p><b>Note:</b> The uploaded answers are automatically saved in Moodle's files area in a directory named “answers” under another directory having name as the name of the quiz for which the answers are uploaded.</p>
+So do not use the characters as mentioned in the section <b>“creating an OMR quiz”</b> for naming the quiz.
+<br/>
+<a id='top' href=''><font size='3' color='blue'>[TOP]</font></a>
+
+<h2 id='Retrieving_earlier_upload_answer_data'>Retrieving earlier uploaded answer data:</h2>
+<p>For retrieving the answer data file already uploaded to Moodle's files area:</p>
+<ol type='a'><li> go to the course under which this quiz is present.</li><br/>
+<li> click on “files” present in the administration block.</li><br/>
+<li> click on folder with the name as the name of the quiz of which you want to access the uploaded answer data file.</li><br/>
+<li> click the “answers” folder and select the file that you want to retrieve.</li>
+</ol>
+<p><b>Note:</b> If a file is uploaded more than once using OMR system's answers upload then these uploaded files are renamed as given below.</p>
+<pre>
+    <b>File name answers</b>
+	1st upload:- answer
+	2nd upload:- answers_1
+	3rd upload:- answers_2 and so on
+
+    so detecting the latest uploaded file becomes easy.
+</pre>
+<a id='top' href=''><font size='3' color='blue'>[TOP]</font></a>
+
+
+
+
+
+
Index: moodle/lang/en_utf8/help/quiz/omrattempts.html
--- moodle/lang/en_utf8/help/quiz/omrattempts.html No Base Revision
+++ moodle/lang/en_utf8/help/quiz/omrattempts.html Locally New
@@ -0,0 +1,19 @@
+<h1>Processing and Viewing Offline Attempts:</h1>
+
+<h2>Processing of offline attempt data:</h2>
+<p>When you are sure that all the uploaded records from scanned OMR data file are correct you can process and evaluate these records. These correct records are also called <b>offline attempts.</b></p>
+
+<ol type='a'><li><b>For processing the answers data</b><br/>
+<ol><li>Click on the OMR tab then click on “process attempts” tab. A list of correct and incorrect records will be displayed.</li><br/>
+<li> Click on “process” button to process the correct records. System will process the correct records and will navigate to results page.</li><br/>
+</ol>
+<p><b>Note:</b> Avoid processing of uploaded records until all the uploaded records are correct.</p>
+</ol>
+
+<h2>Viewing the results of offline attempts:</h2>
+<p>To see the results of offline attempts click on the quiz then click on the results tab. You can see attempt of each student collectively or for a particular question by clicking on the total grade he/she got or the grade he /she got in a particular question.</p>
+
+
+
+
+
Index: moodle/lang/en_utf8/help/quiz/omrattendance.html
--- moodle/lang/en_utf8/help/quiz/omrattendance.html No Base Revision
+++ moodle/lang/en_utf8/help/quiz/omrattendance.html Locally New
@@ -0,0 +1,30 @@
+<h1>Attendance for Offline Quiz</h1>
+<p style='font-size:17px'>
+<br/>
+Attendance for OMR quiz is not compulsory. 
+<br/>But if you upload attendance for an OMR quiz then you have an option to test the validity of the students against this attendance also apart from regular validation against enrollments for the course.
+</p>
+<h2>Structure of the Attendance File:</h2>
+<p>
+&nbsp;&nbsp;&nbsp;Attendance file have roll numbers one at each line like
+<pre>	rollno1
+	rollno2
+	rollno3
+	...
+	...
+	...</pre>
+</p>
+
+<h2>Uploading Attendance:</h2>
+<ol><li>Click on the “omr” tab and then click on attendance tab.</li><br/>
+<li>Click on “browse” under “import from file upload” section and click “upload this file” to upload the attendance file present on your file system.<br/>
+<center>OR</center><br/>
+Click on “choose or upload a file” under “import from file already in course files..” section and click “import from this file” to import the attendance file that is already present in files area of Moodle.</li>
+<br/>
+</ol>
+
+
+
+
+
+
Index: moodle/lang/en_utf8/help/quiz/omrbooklet.html
--- moodle/lang/en_utf8/help/quiz/omrbooklet.html No Base Revision
+++ moodle/lang/en_utf8/help/quiz/omrbooklet.html Locally New
@@ -0,0 +1,50 @@
+<h1>OMR Variant</h1>
+
+<h2>Creating variants:</h2>
+
+<ol>
+	<li><b>Generating Variant Numbers:</b><br/><br/>
+		<ol type='a'>
+			<li> Click on the OMR tab and then variants tab.</li><br/>
+			<li> If not created already, based on the OMR configuration parameter "variantcount" that many number of variants will be created automatically with empty "variantnumber" field and a default question sequence in "question sequence" field. This is the sequence of the questions as present in the master quiz.
+<br/>Note: in the question sequence field each question is represented by its unique id.
+			</li><br/>
+			<li> enter the desired variant number for each of the variants if not done already and click on "save changes" button.<br/>
+			Note: Variant numbers are unique for a quiz</li><br/>
+		</ol>
+	</li><br/>
+	
+
+	<li><b> Deciding Question Sequence for each variant:<br/>
+		There are three options for deciding question sequence for a variant.</b><br/><br/>
+		<ol type='a'>
+			<li> change sequence directly from the text area by placing the question ids at desired place. The sequence should be comma separated with a 0 at the end of the sequence. </li><br/>
+			<li> <b>Automatic Shuffle:</b> For shuffling the question sequence click on the “shuffle” button.<br/>
+				Click on the “save changes” button to save the changes made by shuffling the questions.
+			</li><br/>
+	
+			<li><b> Manual Shuffle:</b> For shuffling questions manually click on the “manual shuffle” button. Use up and down arrows to move a question up and down.</li><br/>
+		</ol>
+	</li><br/>
+
+	
+	<li><b> Adding page breaks:<br/>&nbsp;&nbsp;&nbsp;&nbsp; A page break after a question means the next question will appear on a new page. Page breaks can be added in the question sequence by two ways.</b><br/><br/>
+		<ol type='a'>
+			<li><b> Page break in “question sequence” text area:</b>   add a '0' in the “question sequence” text area at the desired place and click on “save changes” button. </li><br/>
+			<li> <b>Page break using “Manual Shuffle”:</b>   click on “manual shuffle” button then click on “show page breaks” and use up arrow present against last page break to introduce a new page break. Then place it at the desired place using up and down arrows.</li><br/>
+		</ol>
+	</li>
+</ol>
+<h2>Printing Variants:</h2>
+<ol><li><b>If variants are already created then the variants can be viewed and printed.</b></li>
+
+	<ol type='a'><li>Click on “preview” link present against the variant that you wish to preview. A printable version of the variant will be presented on the screen.</li><br/>
+<li> Now click on your browser's print preview option to see the layout of the questions along with page breaks. You can go back and adjust the question sequence or page break position if layout is not proper. </li><br/>
+<li> Click on your web browser's print button to get a hard copy of the quiz paper.</li><br/>
+</ol>
+</li>
+</ol>
+
+
+
+
Index: moodle/lang/en_utf8/help/quiz/omrconfigupload.html
--- moodle/lang/en_utf8/help/quiz/omrconfigupload.html No Base Revision
+++ moodle/lang/en_utf8/help/quiz/omrconfigupload.html Locally New
@@ -0,0 +1,88 @@
+<h1>Creating and Uploading the OMR Configuration File</h1>
+
+<h2>Creating OMR Configuration File</h2>
+<p>
+  The configuration file contains certain parameters that helps in flexible extraction of offline attempt data from the scanned omr answer sheet data file.
+  
+  For structure and contents of configuration file refer to "Structure of configuration file" and "Contents of the configuration file".
+
+  Configuration file can be created once you have scanned OMR answer data file. Based on that file various parameters of configuration file are decided.
+</p>
+<br/>
+<p>1. Structure of Configuration File:<br/>
+<pre>&nbsp;&nbsp;name_of_the_parameter<b>:</b>value_of_the_parameter</pre>
+</p>
+<p>2. Contents of the Configuration File:<br/>
+&nbsp;&nbsp;Following are the contents of the configuration file(order does not matter):
+<table cellpadding=5 cellspacing=5 border=1>
+<thead><th>Parameter</th><th>Value required</th></thead>
+<tbody>
+<tr>
+<td>rollnoposition</td>
+<td>Position of roll number in scanned OMR File.</td>
+</tr>
+<tr>
+<td>rollnolength</td>
+<td>Length of the Roll number</td>
+</tr>
+<tr>
+<td>ansposition</td>
+<td>Position of the answer string in scanned OMR File</td>
+</tr>
+<tr>
+<td>variantposition</td>
+<td>Position of the Variant number in scanned OMR File</td>
+</tr>
+<tr>
+<td>variantlength</td>
+<td>Length of the Variant number</td>
+</tr>
+<tr>
+<td>variantcount</td>
+<td>Number of Variants required for the OMR Quiz</td>
+</tr>
+</tbody>
+</table>
+</p>
+<p>3. Example of configuration file:<br/>
+<pre>&nbsp;&nbsp;&nbsp;&nbsp;variantcount: 4<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;rollnoposition: 1<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;variantposition: 40<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;ansposition: 44<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;rollnolength: 4<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;variantlength: 4<br/>
+</pre>
+</p>
+<p>
+Note: configuration file should be a simple text file. Any other complex format such as MS Word etc
+will not work.
+</p>
+<br/>
+<h2>Uploading OMR Configuration File:</h2>
+<p>
+<ul>
+<li>Click on the OMR tab. System will ask for OMR configuration upload if the configuration file is
+not already uploaded.
+</li>
+<li>Click on “browse” under “import from file upload” section and click “upload this file” to upload the
+configuration file present on your file system.
+<br/>OR<br/>
+Click on “choose or upload a file” under “import from file already in course files..” section and click
+“import from this file” to import the configuration file that is already present in files area of Moodle.
+</li>
+<li>If you are re uploading the OMR configuration file involving a change in the parameter
+“variantcount” then a warning will be shown that:
+</li>
+</ul>
+“if you change the OMR configuration then all the existing answer data and user attempts made on
+that data for this OMR quiz will be erased”.
+Click “yes” if you intend to do so. Click “no” otherwise.
+After the file upload, contents of the file are displayed on the screen.
+Click on the “continue” button to decide the variants of quiz.
+</p>
+
+
+
+
+
+
Index: moodle/lang/en_utf8/help/quiz/omrdiagnostics.html
--- moodle/lang/en_utf8/help/quiz/omrdiagnostics.html No Base Revision
+++ moodle/lang/en_utf8/help/quiz/omrdiagnostics.html Locally New
@@ -0,0 +1,27 @@
+<h1>Analysis and Correcting the Answer Sheet Data:</h1>
+<a href='#top'></a>
+<span>
+<b>Content:</b><ul>
+<li><a href='#Analysis_of_upload_omr_answer_sheet'>Analysis of uploaded File</a></li>
+<li><a href='#Corrective_actions_on_answer_data'>Corrective Actions on Answer Data</a></li>
+</ul>
+</span>
+
+
+
+<h2 id='Analysis_of_upload_omr_answer_sheet'>Analysis of uploaded OMR answer sheet data:</h2>
+<p>Answer data analysis is done for detecting problems with the uploaded records. There are two types of analysis available for uploaded answer data.</p>
+<ol type='a'><li><b>Record wise analysis:</b><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; When you upload the answer data then the system automatically performs the analysis and shows it record by record. If answers were already uploaded then just click the “upload answers” tab to see the record wise analysis of answer data.</li><br/>
+<li><b>Error category wise analysis:</b><br/>&nbsp;&nbsp;&nbsp;&nbsp; Under the “upload answers” tab click on the “diagnostics:” list and choose “category wise” and click on “show” button.</li></ol>
+<p>Diagnostics will be shown based on error category.</p>
+<a id='top' href=''><font size='3' color='blue'>[TOP]</font></a>
+
+
+
+<h2 id='Corrective_actions_on_answer_data'>Corrective actions on answer data:</h2>
+<p>After detecting the problems with the uploaded data you can go and manually change a copy of Scanned OMR data file.</p>
+<p>After seeing the diagnostics the user should manually change the problematic records in the scanned answers file and re upload that file to system.</p>
+<p>For re uploading an answer file go to “upload answers” tab and click on the “change” button present at the bottom of the page and follow the procedure as described in “Upload answers” section above.</p>
+<p><b>NOTE:</b> Do not change original scanned OMR data file. Always make a copy of it and do the changes on that file.</p>
+<a id='top' href=''><font size='3' color='blue'>[TOP]</font></a>
+
Index: moodle/lang/en_utf8/help/quiz/quiztype.html
--- moodle/lang/en_utf8/help/quiz/quiztype.html No Base Revision
+++ moodle/lang/en_utf8/help/quiz/quiztype.html Locally New
@@ -0,0 +1,8 @@
+<h2>Quiz Type</h1>
+<p>There are two type of quiz:
+<ul> 
+<li>Default  -  Select "omr" to create the omr quiz.</li>
+<li>OMR type -  Selecting "default" makes it a normal online quiz.</li>
+</ul>
+</br>
+</p>
Index: moodle/mod/quiz/edit.php
--- moodle/mod/quiz/edit.php Base (1.107.2.13)
+++ moodle/mod/quiz/edit.php Locally Modified (Based On 1.107.2.13)
@@ -169,6 +169,16 @@
         }
     }
 
+//--------------------------------------------For OMR Quiz,------------------------------------------------
+	$omrquiz = get_record("omrquiz", "quizid", $cm->instance);
+	$flag=false;
+	if(record_exists('omrquiz_booklet', 'omrquizid', $omrquiz->id) &&
+	   !record_exists('omrquiz_answers', 'omrquizid', $omrquiz->id)){
+		$flag=true;
+		$recordstoupdate=get_records('omrquiz_booklet', 'omrquizid', $omrquiz->id,'' , 'id, questionsequence') ;
+	}
+//----------------------------------------author@ Harmeet Saini---------------------------------------------
+
     if (($addquestion = optional_param('addquestion', 0, PARAM_INT)) and confirm_sesskey()) { /// Add a single question to the current quiz
         quiz_add_quiz_question($addquestion, $quiz);
         $significantchangemade = true;
Index: moodle/mod/quiz/mod_form.php
--- moodle/mod/quiz/mod_form.php Base (1.28.2.11)
+++ moodle/mod/quiz/mod_form.php Locally Modified (Based On 1.28.2.11)
@@ -26,6 +26,14 @@
         $mform->setType('intro', PARAM_RAW);
         $mform->setHelpButton('intro', array('richtext', get_string('helprichtext')));
 
+//---------------------------------------------------For OMR Quiz,------------------------------------------------
+	// element of "select" type for "type of quiz". Possible values are "default" or "omr". 
+		$mform->addElement('header', 'omr', get_string('omr_quiz_type','quiz'));		
+		$quiztype=array('default'=>'default','omr'=>'omr');
+		$mform->addElement('select', 'quiztype',get_string('omr_type_of_quiz', 'quiz'), $quiztype);		   //edited by Jalpa
+		$mform->setHelpButton('quiztype', array('quiztype', get_string('omr_quiz_type', 'quiz'), 'quiz'));   ///edited by Jalpa
+//----------------------------------------------author@ Harmeet Saini---------------------------------------------
+
 //-------------------------------------------------------------------------------
         $mform->addElement('header', 'timinghdr', get_string('timing', 'form'));
         $mform->addElement('date_time_selector', 'timeopen', get_string('quizopen', 'quiz'), array('optional'=>true));
Index: moodle/mod/quiz/omr.php
--- moodle/mod/quiz/omr.php No Base Revision
+++ moodle/mod/quiz/omr.php Locally New
@@ -0,0 +1,767 @@
+<?php
+/**
+ * This page is for question paper variant management.
+ * Questions in a particular variant can be shuffled manually or automatically.
+ * 
+ * @author Harmeet Saini
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package quiz
+ */
+
+require_once("../../config.php");
+require_once($CFG->dirroot.'/mod/quiz/editlib.php');
+
+Global $USER;
+$id   = optional_param('cmid', 0, PARAM_INT); // course module id not quiz id
+$q    = optional_param('q',  0, PARAM_INT);  // quiz ID
+$tempseq=array(); //for shuffling purpose. It will hold temporary sequence of shuffled questions for each booklet untill "save" button pressed.
+ 
+if (! $cm = get_coursemodule_from_id('quiz', $id)) {
+	error("There is no coursemodule with id $id");
+}
+
+if (! $course = get_record("course", "id", $cm->course)) {
+	error("Course is misconfigured");
+}
+
+if (! $quiz = get_record("quiz", "id", $cm->instance)) {
+	error("The quiz with id $cm->instance corresponding to this coursemodule $id is missing");
+}
+
+// $cm->id gives course module id as in mdl_course_module.
+// $cm->instance gives corresponding coursemodule instance id(or quiz id as in mdl_quiz table if module=12).
+if (! $omrquiz = get_record("omrquiz", "quizid", $cm->instance)) {
+	error("The specified omrquiz does not exist");
+}
+
+if($omrquiz->bookletcount==0){
+	redirect("$CFG->wwwroot/mod/quiz/omruploadconfig.php?cmid=$id", "Upload configuration file first..",1);
+}
+
+$countbooklets=$omrquiz->bookletcount; 
+
+//this loop will run on every execution of this page no matter required or not...fix it by introducing some check.
+for($k=1;$k<=$countbooklets;$k++){
+	
+	//$index refers to id(in mdl_omrquiz_booklet) of the booklet which is needed to be shuffled.
+	if($index=optional_param('shuffleid'.$k,NULL,PARAM_CLEAN)){
+
+		if($tempsequence=optional_param('tempseq'.$k,NULL,PARAM_CLEAN)){
+
+			$tempseq[$index]=$tempsequence;	// maintaining the temporary sequence of questions before user clikced the save button
+
+		}
+	}
+}
+
+$shufflemanually=false;
+$indexformanualshuffle=null;	// id of the booklet that is set for manual shuffle (id in mdl_omrquiz_booklet).
+$currentshuffleid=null;			// id of the booklet that is requested to shuffle currently.
+
+for($k=1;$k<=$countbooklets;$k++){
+
+	if(optional_param('manualshuffle'.$k,NULL,PARAM_CLEAN)){
+		$shufflemanually=true;
+
+		$indexformanualshuffle=$k;
+	}
+
+	if(optional_param('shufflebutton'.$k,NULL,PARAM_CLEAN)){
+		if($currentshuffleid=optional_param('shuffleid'.$k,NULL,PARAM_CLEAN)){
+			if(!$tempseq[$currentshuffleid]){
+				error("there must be something wrong "); //delete this if cond. if its not reached here even after some significant testing.
+			}
+
+			$questions=explode(',',$tempseq[$currentshuffleid]);
+			$countsequence=count($questions);
+
+			foreach($questions as $key=> $value){
+				if($value==0){
+					$pagebreakposition[]=$key;
+					unset($questions[$key]);
+				}
+			}
+			$questions=implode(',',$questions);
+			$questions=explode(',',$questions);
+			$tempquestions=swapshuffle($questions);
+			$pagebreakcounter=count($pagebreakposition);
+			$count=0;
+			for($i=0;$i<$countsequence;$i++){
+				$set=false;
+				for($z=0;$z<$pagebreakcounter;$z++){
+					if($i==$pagebreakposition[$z]){
+						$questions[$i]=0;
+						$count+=1;
+						$set=true;
+						break;
+					}
+					if(!$set){
+						$questions[$i]=$tempquestions[$i-$count];
+					}
+
+				}
+
+			}
+
+			$tempseq[$currentshuffleid]= implode(',',$questions);
+			$tempseq[$currentshuffleid]=trim($tempseq[$currentshuffleid]);
+		}
+	}
+}
+
+
+//for getting existing booklets information
+if($omrquiz_booklets=get_records('omrquiz_booklet', 'omrquizid', $omrquiz->id, $sort='id')){
+	$l=1;
+	foreach($omrquiz_booklets as $key=>$value){
+		$bookletnoarray[$l]=$value->bookletno;
+		$bookletidarray[$l]=$key;
+		$l+=1;
+			
+	}
+	$firstbookletid=$bookletidarray[1];    //remains zero after first "save changes" is made
+}
+
+
+//------------------- code for right column i.e. for manual shuffling.-----------------
+$thispageurl=new moodle_url;
+$thispageurl->param('cmid', $cm->id); // have a close check on this
+$bookletid=optional_param('bookletid',NULL,PARAM_CLEAN);
+
+$quiz_showbreaks = optional_param('showbreaks', -1, PARAM_BOOL);
+$quiz_reordertool = optional_param('reordertool', 0, PARAM_BOOL);
+
+if ($quiz_showbreaks > -1) {
+	$thispageurl->param('showbreaks', $quiz_showbreaks);
+} else {
+	$quiz_showbreaks = ($CFG->quiz_questionsperpage < 2) ? 0 : 1;
+}
+if ($quiz_reordertool != 0) {
+	$thispageurl->param('reordertool', $quiz_reordertool);
+}
+
+
+/// Now, check for commands on this page and modify variables as necessary
+// If any edit action makes a significant change to the structure of the quiz, then we
+// will need to delete all preview attempts.
+$significantchangemade = false;
+
+if (($up = optional_param('up', false, PARAM_INT)) !== false and confirm_sesskey()) { /// Move the given question up a slot
+
+	$questions = explode(",", $omrquiz_booklets[$bookletid]->questionsequence);
+	if ($up > 0 and isset($questions[$up])) {
+		$prevkey = ($questions[$up-1] == 0) ? $up-2 : $up-1;
+		$swap = $questions[$prevkey];
+		$questions[$prevkey] = $questions[$up];
+		$questions[$up]   = $swap;
+		$omrquiz_booklets[$bookletid]->questionsequence = implode(",", $questions);
+
+		// Always have a page break at the end
+		$omrquiz_booklets[$bookletid]->questionsequence = $omrquiz_booklets[$bookletid]->questionsequence . ',0';
+		// Avoid duplicate page breaks
+		$omrquiz_booklets[$bookletid]->questionsequence = str_replace(',0,0', ',0', $omrquiz_booklets[$bookletid]->questionsequence);
+		if (!set_field('omrquiz_booklet', 'questionsequence', $omrquiz_booklets[$bookletid]->questionsequence, 'id', $bookletid)) {
+			error('Could not save question list');
+		}
+		$significantchangemade = true;
+	}
+}
+if (($delete = optional_param('delete', false, PARAM_INT)) !== false and confirm_sesskey()) { /// Remove a pagebreak from the booklet
+	$sequence=$omrquiz_booklets[$bookletid]->questionsequence;
+	$questions = explode(",", $sequence);
+	if (!isset($questions[$delete])) {
+		error("Page break position to delete is incorrect");
+	}
+
+	//$question = $questions[$id];
+	unset($questions[$delete]);
+
+	$sequence = implode(",", $questions);
+	// Avoid duplicate page breaks
+	$sequence = str_replace(',0,0', ',0', $sequence);
+	$omrquiz_booklets[$bookletid]->questionsequence=$sequence;
+	if (!set_field('omrquiz_booklet', 'questionsequence', $sequence, 'omrquizid', $omrquiz->id, 'id', $bookletid)) {
+		error('Could not save question list');
+	}
+	$shufflemanually=true;
+
+	$significantchangemade = true;
+}
+
+
+if (($down = optional_param('down', false, PARAM_INT)) !== false and confirm_sesskey()) { /// Move the given question down a slot
+	$questions = explode(",", $omrquiz_booklets[$bookletid]->questionsequence);
+	if ($down < count($questions)) {
+		$nextkey = ($questions[$down+1] == 0) ? $down+2 : $down+1;
+		$swap = $questions[$nextkey];
+		$questions[$nextkey] = $questions[$down];
+		$questions[$down]   = $swap;
+		$omrquiz_booklets[$bookletid]->questionsequence = implode(",", $questions);
+			
+		// Avoid duplicate page breaks
+
+		$omrquiz_booklets[$bookletid]->questionsequence = str_replace(',0,0', ',0', $omrquiz_booklets[$bookletid]->questionsequence);
+		if (!set_field('omrquiz_booklet', 'questionsequence', $omrquiz_booklets[$bookletid]->questionsequence, 'id', $bookletid)) {
+			error('Could not save question list');
+		}
+		$significantchangemade = true;
+	}
+}
+
+if (optional_param('repaginate', false, PARAM_BOOL) and confirm_sesskey()) { /// Re-paginate the quiz
+	$shufflemanually=true;
+
+	$oldquestions = explode(",", $omrquiz_booklets[$bookletid]->questionsequence); // the questions in the old order
+	$questionss = array(); // for questions in the new order
+	$reorderdata = (array) data_submitted();
+
+	foreach ($reorderdata as $key => $value) {
+		if (preg_match('!^o([0-9]+)$!', $key, $matches)) {
+			$key = $matches[1];
+
+			// Make sure two questions don't overwrite each other. If we get a second
+			// question with the same position, shift the second one along to the next gap.
+			while (array_key_exists($value, $questionss)) {
+					
+				$value++;
+			}
+			$questionss[$value] = $oldquestions[$key];
+
+		}
+	}
+
+	// If ordering info was given, reorder the questions
+	if ($questionss) {
+		ksort($questionss);
+		// Make sure that the quiz does not start with a page break.
+		while (reset($questionss) == '0') {
+			array_shift($questionss);
+		}
+		
+		$omrquiz_booklets[$bookletid]->questionsequence = implode(",", $questionss);
+		// Always have a page break at the end
+		$omrquiz_booklets[$bookletid]->questionsequence = $omrquiz_booklets[$bookletid]->questionsequence . ',0';
+		// Avoid duplicate page breaks
+		while (strpos($omrquiz_booklets[$bookletid]->questionsequence, ',0,0')) {
+			$omrquiz_booklets[$bookletid]->questionsequence = str_replace(',0,0', ',0', $omrquiz_booklets[$bookletid]->questionsequence);
+		}
+		if (!set_field('omrquiz_booklet', 'questionsequence', $omrquiz_booklets[$bookletid]->questionsequence, 'id', $bookletid)) {
+			error('Could not save question list');
+		}
+	}
+	$significantchangemade = true;
+}
+
+if( $up or $down or $down===0 or $quiz_reordertool or $quiz_showbreaks or optional_param("shufflemanually",false,PARAM_CLEAN)){
+	$shufflemanually=true;
+}
+
+/// Delete any teacher preview attempts if the quiz has been modified
+if ($significantchangemade) {
+	$previewattempts = get_records_select('quiz_attempts',
+                'quiz = ' . $quiz->id . ' AND preview = 1');
+	if ($previewattempts) {
+		foreach ($previewattempts as $attempt) {
+			quiz_delete_attempt($attempt, $quiz);
+		}
+	}
+}
+
+
+require_login($course->id, false, $cm);
+$context = get_context_instance(CONTEXT_MODULE, $cm->id);
+// if no questions have been set up yet redirect to edit.php
+if (!$quiz->questions and has_capability('mod/quiz:manage', $context)){
+	//no questions added, redirect to edit page
+	redirect($CFG->wwwroot . '/mod/quiz/edit.php?cmid=' . $cm->id);
+}
+
+add_to_log($course->id, "omr-quiz", "edit", "omr.php?id=$cm->id", $quiz->id, $cm->id);
+
+$navigation = build_navigation(get_string('editing_omr_quiz','quiz'), $cm);     //edited by Jalpa  
+print_header_simple(get_string('editing_omr_quiz','quiz'), '', $navigation, "", "", true, "");   //edited by Jalpa  
+$currenttab = 'omr';
+$mode = 'booklets';   // mode is the subtab that is first activated on cliking the main tab.
+include('tabs.php');
+
+
+if (optional_param('savechanges', false, PARAM_BOOL) and confirm_sesskey()){
+	//when no booklet already exists for this quiz
+	if (! $omrquiz_booklets) {
+		$issetallbooklets=true;		//boolean flag to check wheather info is added for all the booklets?
+		for($i=1;$i<=$omrquiz->bookletcount;$i++){
+			$temp=trim(optional_param('bookletno'.$i, 0, PARAM_CLEAN));
+			if($temp==""){
+				$issetallbooklets=false;
+			}else{
+				$isduplicatebookletno[]=$temp;
+			}
+				
+		}
+		$a=count($isduplicate=array_unique($isduplicatebookletno));
+
+		if(!$issetallbooklets){
+			notify("Enter information for all the booklets, changes are not saved..");
+		}
+		else if( $a != $omrquiz->bookletcount and $issetallbooklets){
+			notify("Booklet numbers should be unique for a quiz, changes are not saved..");
+		}
+		else{
+			for($i=1;$i<=$omrquiz->bookletcount;$i++){
+				$omrquiz_booklet=new object(); // place this before the loop....ensure that functioning doesnt get affected by doing so
+				$omrquiz_booklet->omrquizid=$omrquiz->id;
+				$omrquiz_booklet->bookletno=optional_param('bookletno'.$i, 0, PARAM_CLEAN);
+				$omrquiz_booklet->questionsequence=optional_param('qseq'.$i, '', PARAM_SEQUENCE);
+
+				if(!insert_record('omrquiz_booklet', $omrquiz_booklet, $returnid=false, $primarykey='id')){
+					error("could not insert omrbooklet data in table omrquiz_booklet");
+				}
+			}
+			if($omrquiz_booklets=get_records('omrquiz_booklet', 'omrquizid', $omrquiz->id, $sort='id')){
+				$l=1;
+
+				foreach($omrquiz_booklets as $key=>$value){
+					$bookletnoarray[$l]=$value->bookletno;
+					$bookletidarray[$l]=$key;
+					$l+=1;
+				}
+			}
+		}
+	}
+
+	//booklets already exist for this quiz
+	else{
+
+		$issetallbooklets=true;		//boolean flag to check wheather info is added for all the booklets?
+		for($i=1;$i<=$omrquiz->bookletcount;$i++){
+			$temp=trim(optional_param('bookletno'.$i, 0, PARAM_CLEAN));
+			if($temp==""){
+				$issetallbooklets=false;
+			}else{
+				$isduplicatebookletno[]=$temp;
+			}
+				
+		}
+		$a=count($isduplicate=array_unique($isduplicatebookletno));
+
+		if(!$issetallbooklets){
+			notify("Enter information for all the booklets, changes are not saved..");
+		}
+		else if( $a != $omrquiz->bookletcount and $issetallbooklets){
+			notify("Booklet numbers should be unique for a quiz, changes are not saved..");
+		}
+		else{
+			$j=$firstbookletid+$omrquiz->bookletcount;
+			for($i=$firstbookletid, $count=1;$i<$j;$i++,$count++){
+				$omrquiz_booklet_update=new object();// place this before the loop....ensure that functioning doesnt get affected by doing so
+				$omrquiz_booklet_update->id=$i;
+				$omrquiz_booklet_update->omrquizid=$omrquiz->id;
+				$omrquiz_booklet_update->bookletno=optional_param('bookletno'.$count, 0, PARAM_CLEAN);
+				$omrquiz_booklet_update->questionsequence=optional_param('qseq'.$count, '', PARAM_SEQUENCE);
+				if(!update_record('omrquiz_booklet', $omrquiz_booklet_update)){
+					error("could not update omrbooklet data in table omrquiz_booklet");
+				}
+			}
+
+			if($omrquiz_booklets=get_records('omrquiz_booklet', 'omrquizid', $omrquiz->id, $sort='id')){
+				$l=1;
+				foreach($omrquiz_booklets as $key=>$value){
+					$bookletnoarray[$l]=$value->bookletno;
+					$bookletidarray[$l]=$key;
+					$l+=1;
+
+				}
+				$firstbookletid=$bookletidarray[1];
+			}
+		}
+		unset($tempseq);
+	}
+}
+
+echo '<table border="0" style="width:100%" cellpadding="2" cellspacing="0">';
+if(!$shufflemanually){
+	echo '<tr><td style="width:100%" valign="top">';
+}
+else{
+	echo '<tr><td style="width:50%" valign="top">';
+}
+print_box_start();
+
+//print_heading(get_string('variantheading','quiz'),"", 3);         //edited by Jalpa
+print_heading_with_help(get_string('variantheading','quiz'),'omrbooklet','quiz',NULL,false);   //edited by Jalpa
+
+echo "<form name=\"myform\" method=\"post\" action=\"omr.php?cmid=$cm->id\">";
+echo '<fieldset class="invisiblefieldset" style="display: block;">';
+echo "<input type=\"hidden\" name=\"sesskey\" value=\"$USER->sesskey\" />";
+//echo $pageurl->hidden_params_out();
+echo "<table style=\"width:100%;\">\n";
+echo "<tr><th align=\"left\" class=\"header\" scope=\"col\">#</th>";
+echo "<th align=\"left\" style=\"white-space:nowrap;\" class=\"header\" scope=\"col\">".get_string('bookletheading','quiz')."</th>";   //edited by Jalpa  
+echo "<th align=\"left\" style=\"white-space:nowrap;\" class=\"header\" scope=\"col\">".get_string('questionsequence','quiz')."</th>";   //edited by Jalpa  
+if($omrquiz_booklets){
+	echo "<th align=\"center\" class=\"header\" scope=\"col\">Action</th>";
+}
+
+echo "</tr>\n";
+if(isset($firstbookletid)){
+	$booklet=$firstbookletid;
+}
+if(!$omrquiz_booklets){
+	for($i=1;$i <= $omrquiz->bookletcount;$i++){
+		echo "<tr><td>$i</td>";
+		echo "<td>";
+		echo '<input type="text" name="bookletno'.$i.'" value="" size="4" />';
+		echo"</td>";
+		echo "<td>";
+		echo '<input type="text" name="qseq'.$i.'" value="'.$quiz->questions.'" size="20" />';
+		echo "</td>";
+		echo '<td align="center">';
+		echo "</tr>";
+	}
+}
+
+elseif($booklet){
+	//processing when buklets are already present and save changes are made more thn once
+	// if possible use foreach loop because here an assumption is made that starting from a particular id for a booklet(e.g. 48) the next booklet must have consecutive id.
+	for($i=1;$i <= $omrquiz->bookletcount;$i++,$booklet++){   
+		echo "<tr><td>$i</td>";
+		echo "<td>";
+
+		if(record_exists('omrquiz_answers', 'omrquizid', $omrquiz->id)){
+			echo '<input type="text" name="bookletno'.$i.'" value="'.$omrquiz_booklets[$booklet]->bookletno.'" size="4" disabled="disabled" />';
+		}else{
+			echo '<input type="text" name="bookletno'.$i.'" value="'.$omrquiz_booklets[$booklet]->bookletno.'" size="4" />';
+		}
+
+		echo"</td>";
+		echo "<td>";
+		//if($currentshuffleid){
+			if($tempseq[$currentshuffleid] and $booklet==$currentshuffleid){
+				if(record_exists('omrquiz_answers', 'omrquizid', $omrquiz->id)){
+					echo '<input type="text" name="qseq'.$i.'" value="'.$tempseq[$currentshuffleid].'" size="20" disabled="disabled" />';
+				}else{
+					echo '<input type="text" name="qseq'.$i.'" value="'.$tempseq[$currentshuffleid].'" size="20" />';
+				}
+				
+				echo '<input type="hidden" name="tempseq'.$i.'" value="'.$tempseq[$currentshuffleid].'" />';
+		//	}
+		}elseif(!isset($tempseq[$booklet])){
+			if(record_exists('omrquiz_answers', 'omrquizid', $omrquiz->id)){
+				echo '<input type="text" name="qseq'.$i.'" value="'.$omrquiz_booklets[$booklet]->questionsequence.'" size="20" disabled="disabled" />';
+			}else{
+				echo '<input type="text" name="qseq'.$i.'" value="'.$omrquiz_booklets[$booklet]->questionsequence.'" size="20" />';
+			}
+			echo '<input type="hidden" name="tempseq'.$i.'" value="'.$omrquiz_booklets[$booklet]->questionsequence.'" />';
+		}
+		else{
+			if(record_exists('omrquiz_answers', 'omrquizid', $omrquiz->id)){
+				echo '<input type="text" name="qseq'.$i.'" value="'.$tempseq[$booklet].'" size="20" disabled="disabled" />';
+			}else{
+				echo '<input type="text" name="qseq'.$i.'" value="'.$tempseq[$booklet].'" size="20" />';
+			}
+			echo '<input type="hidden" name="tempseq'.$i.'" value="'.$tempseq[$booklet].'" />';
+		}
+		echo "</td>";
+
+
+		//shuffleid gives id in omrquiz_booklet table.
+		echo "<td align=\"center\">";
+		if(record_exists('omrquiz_answers', 'omrquizid', $omrquiz->id)){
+			// do not show the button
+		}else{
+			echo '<input type="submit" name="manualshuffle'.$i.'" value="manual shuffle"/>';
+			echo"&nbsp";
+		}
+
+		if(record_exists('omrquiz_answers', 'omrquizid', $omrquiz->id)){
+			// do not show the button
+		}else{
+			echo '<input type="submit" name="shufflebutton'.$i.'" value="shuffle"  />';
+			echo"&nbsp";
+		}
+
+		echo '<a href="'.$CFG->wwwroot.'/mod/quiz/omrpreview.php?cmid='.$cm->id.'&omrquizid='.$omrquiz->id.'& bookletid='.$booklet.'">preview</a>';
+		echo '<input type="hidden" name="shuffleid'.$i.'" value="'.$booklet.'"/>';
+
+		echo "</td>";
+
+		echo '<td align="center">';
+		echo "</tr>";
+	}
+}
+//after clicking save changes for the first time... coz $key is not set yet
+else{
+	//echo"<br>processing when booklets are already present and "save changes" is made for the first time<br>";
+
+	$i=1;
+	foreach($omrquiz_booklets as $key=>$value){
+		echo "<tr><td>$i</td>";
+		echo "<td>";
+		echo '<input type="text" name="bookletno'.$i.'" value="'.$value->bookletno.'" size="4" />';
+		echo"</td>";
+		echo "<td>";
+		echo '<input type="text" name="qseq'.$i.'" value="'.$value->questionsequence.'" size="20" />';
+		echo "</td>";
+		echo "<td align=\"center\">";
+		//onClick="'.shuffle($omrquiz_booklet[$key]->questionsequence).'"
+		echo '<input type="hidden" name="shuffleid'.$i.'" value="'.$key.'"/>';
+		echo '<input type="hidden" name="tempseq'.$i.'" value="'.$value->questionsequence.'" />';
+		echo '<input type="submit" name="manualshuffle'.$i.'" value="manual shuffle"/>';
+		echo '<input type="submit" name="shufflebutton'.$i.'" value="shuffle"/>';
+		echo '<a href="'.$CFG->wwwroot.'/mod/quiz/omrpreview.php?cmid='.$cm->id.'&omrquizid='.$omrquiz->id.'& bookletid='.$value->id.'"> preview</a>';
+		echo "</td>";
+		echo '<td align="center">';
+		echo "</tr>";
+		$i+=1;
+	}
+}
+echo "</table>";
+echo"<br>";
+echo"<br>";
+if(record_exists('omrquiz_answers', 'omrquizid', $omrquiz->id)){
+	//do not show the save button
+}else{
+	echo '<div class="quizquestionlistcontrols"><input type="submit" name=savechanges value="'.get_string('savechanges').'" />';
+}
+echo '</fieldset>';
+echo "</form>\n";
+print_box_end();
+echo '</td>';
+
+
+
+if($indexformanualshuffle){
+	$bookletno=$bookletnoarray[$indexformanualshuffle];
+	$bookletid=$bookletidarray[$indexformanualshuffle];
+}
+
+
+
+if($shufflemanually){
+	if($bookletid=optional_param('bookletid',NULL,PARAM_CLEAN)){
+		//echo"booklet id is taken from page post variable";
+	}else{
+		$bookletid=$bookletidarray[$indexformanualshuffle];
+	}
+	$bookletno=$omrquiz_booklets[$bookletid]->bookletno;
+	$questionseq=$omrquiz_booklets[$bookletid]->questionsequence;
+
+	echo '<td style="width:50%" valign="top">';
+	print_box_start();
+	print_heading("Questions in booklet $bookletno","", 4);
+	//echo"questions in this booklet are $questionseq";
+	print_omrquestion_list($questionseq, $quiz,$bookletid, $thispageurl,  $quiz_showbreaks, $quiz_reordertool);
+	//echo '<input type="hidden" name="bookletid" value="'.$bookletid.'" />';
+	print_box_end();
+
+	echo '</td>';
+}
+echo '</tr>';
+echo '</table>';
+
+print_footer($course);
+
+
+//-------------------------------------functions----------------------------------------
+
+/**
+ * Prints the questions present in the currently selected variant for manual shuffle.
+ * questions can be shuffled manually by using up and down arrows.
+ * Also page break can be added between the questions. Reordering tool is also provided.
+ * 
+ * @param string  $questionseq comma separated values of question ids
+ * @param object  $quiz
+ * @param string  $bookletid
+ * @param object  $pageurl
+ * @param boolean $showbreaks
+ * @param boolean $reordertool
+ * @return boolean
+ */
+function print_omrquestion_list($questionseq,$quiz,$bookletid, $pageurl,  $showbreaks=true, $reordertool=false) {
+	global $USER, $CFG, $QTYPES;
+	$strorder = get_string("order");
+	$strquestionname = get_string("questionname", "quiz");
+	$strview = get_string("view");
+	$straction = get_string("action");
+	$strmoveup = get_string("moveup");
+	$strmovedown = get_string("movedown");
+	$strremove = get_string('remove', 'quiz');
+	$strtype = get_string("type", "quiz");
+	$strpreview = get_string("preview", "quiz");
+
+	if (!$questionseq) {// modify the internal contents
+		echo "<p class=\"quizquestionlistcontrols\">";
+		print_string("noquestions", "quiz");
+		echo "</p>";
+		return 0;
+	}
+
+	if (!$questions = get_records_sql("SELECT q.*,c.contextid
+	FROM {$CFG->prefix}question q,
+	{$CFG->prefix}question_categories c
+	WHERE q.id in ($questionseq)
+	AND q.category = c.id")) {
+		echo "<p class=\"quizquestionlistcontrols\">";
+		print_string("noquestions", "quiz");
+		echo "</p>";
+		return 0;
+	}
+
+	$count = 0;
+	$qno = 1;
+	$order = explode(',', $questionseq);
+	$lastindex = count($order)-1;
+	// If the list does not end with a pagebreak then add it on.
+	if ($order[$lastindex] != 0) {
+		$order[] = 0;
+		$lastindex++;
+	}
+
+	//form for manual shuffling
+	echo "<form method=\"post\" action=\"omr.php\">";  // this needs to be looked at
+	echo '<fieldset class="invisiblefieldset" style="display: block;">';
+	echo "<input type=\"hidden\" name=\"sesskey\" value=\"$USER->sesskey\" />";
+
+	echo '<input type="hidden" name="bookletid" value="'.$bookletid.'" />';
+	echo $pageurl->hidden_params_out();
+
+	echo "<table style=\"width:100%;\">\n";
+	echo "<tr><th colspan=\"3\" style=\"white-space:nowrap;\" class=\"header\" scope=\"col\">$strorder</th>";
+	echo "<th class=\"header\" scope=\"col\">#</th>";
+	echo "<th align=\"left\" style=\"white-space:nowrap;\" class=\"header\" scope=\"col\">$strquestionname</th>";
+	echo "<th align=\"center\" style=\"white-space:nowrap;\" class=\"header\" scope=\"col\">$straction</th>";
+	echo "</tr>\n";
+
+
+	foreach ($order as $i => $qnum) { //here $qnum gives id of the question as in mdl_questions.
+			
+			
+		if ($qnum and empty($questions[$qnum])) {
+			continue;
+		}
+
+
+
+		// If the questiontype is missing change the question type
+		if ($qnum and !array_key_exists($questions[$qnum]->qtype, $QTYPES)) {
+			$questions[$qnum]->qtype = 'missingtype';
+		}
+
+		// Show the re-ordering field if the tool is turned on.
+		// But don't show it in front of pagebreaks if they are hidden.
+		if ($reordertool) {
+
+
+			if ($qnum or $showbreaks) {
+					
+				echo '<tr><td><input type="text" name="o'.$i.'" size="2" value="'.(10*$count+10).'" /></td> ';
+
+
+			} else {
+					
+				echo '<tr><td><input type="hidden" name="o'.$i.'" size="2" value="'.(10*$count+10).'" /></td> ';
+			}
+		} else {
+			echo '<tr><td></td>';
+		}
+		if ($qnum == 0) { // This is a page break
+			if ($showbreaks) {
+				echo '<td colspan ="3">&nbsp;</td>';
+				echo '<td><table style="width:100%; line-height:11px; font-size:9px; margin: -5px -5px;"><tr>';
+				echo '<td><hr /></td>';
+				echo '<td style="width:50px;">Page break</td>';
+				echo '<td><hr /></td>';
+				echo '<td style="width:45px;">';
+				if ($count > 1) {
+
+
+					echo "<a title=\"$strmoveup\" href=\"".$pageurl->out_action(array('up'=>$count, 'bookletid'=>$bookletid))."\"><img
+					src=\"$CFG->pixpath/t/up.gif\" class=\"iconsmall\" alt=\"$strmoveup\" /></a>";
+				}
+				echo '&nbsp;';
+				if ($count < $lastindex) {
+					echo "<a title=\"$strmovedown\" href=\"".$pageurl->out_action(array('down'=>$count, 'bookletid'=>$bookletid))."\"><img
+					src=\"$CFG->pixpath/t/down.gif\" class=\"iconsmall\" alt=\"$strmovedown\" /></a>";
+
+					echo "<a title=\"$strremove\" href=\"".$pageurl->out_action(array('delete'=>$count, 'bookletid'=>$bookletid))."\">
+					<img src=\"$CFG->pixpath/t/delete.gif\" class=\"iconsmall\" alt=\"$strremove\" /></a>";
+				}
+				echo '</td></tr></table></td>';
+				echo '<td colspan="2">&nbsp;</td>';
+			}
+			$count++;
+			// missing </tr> here, if loop is broken, need to close the </tr>
+			echo "</tr>";
+			continue;
+		}
+		$question = $questions[$qnum];
+
+		echo "<td>";
+		if ($count != 0) {
+			echo "<a title=\"$strmoveup\" href=\"".$pageurl->out_action(array('up'=>$count, 'bookletid'=>$bookletid))."\"><img
+			src=\"$CFG->pixpath/t/up.gif\" class=\"iconsmall\" alt=\"$strmoveup\" /></a>";
+		}
+		echo "</td>";
+		echo "<td>";
+		if ($count < $lastindex-1) {
+			echo "<a title=\"$strmovedown\" href=\"".$pageurl->out_action(array('down'=>$count, 'bookletid'=>$bookletid))."\"><img
+			src=\"$CFG->pixpath/t/down.gif\" class=\"iconsmall\" alt=\"$strmovedown\" /></a>";
+		}
+		echo "</td>";
+
+		// Print and increment question number
+		echo '<td>'.($question->length ? $qno : '&nbsp;').'</td>';
+		$qno += $question->length;
+
+
+		echo '<td>' . format_string($question->name) . '</td>';
+		echo'<td align="center">';
+
+		if (($question->qtype != 'random')){
+			echo quiz_question_preview_button($quiz, $question);
+		}
+
+		echo "</td></tr>";
+		$count++;
+			
+	}
+
+
+	echo"</table>\n";
+
+	echo '<div class="quizquestionlistcontrols"><input type="submit" name="repaginate" value="'. get_string('go') .'" />';
+	echo '<input type="hidden" name="repaginate" value="'. get_string('go') .'" /></div>';
+	echo '</fieldset>';
+	echo "</form>\n";
+
+	/// Form to choose to show pagebreaks and to repaginate quiz
+	echo '<form method="post" action="omr.php" id="showbreaks">';
+	echo '<fieldset class="invisiblefieldset">';
+	echo '<input type="hidden" name="bookletid" value="'.$bookletid.'" />';
+	echo $pageurl->hidden_params_out(array('showbreaks', 'reordertool'));
+	echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
+	echo '<input type="hidden" name="showbreaks" value="0" />';
+	echo '<input type="hidden" name="shufflemanually" value="true" />';
+	echo '<input type="checkbox" name="showbreaks" value="1"';
+	if ($showbreaks) {
+		echo ' checked="checked"';
+	}
+	echo ' onclick="form.submit(); return true;" />';
+	print_string('showbreaks', 'quiz');
+	echo '<br /><input type="hidden" name="reordertool" value="0" />';
+	echo '<input type="checkbox" name="reordertool" value="1"';
+	if ($reordertool) {
+		echo ' checked="checked"';
+	}
+	echo ' onclick="form.submit(); return true;" />';
+	print_string('reordertool', 'quiz');
+	echo ' ';
+	helpbutton('reorderingtool', get_string('reordertool', 'quiz'), 'quiz');
+
+
+	echo '</fieldset>';
+	echo '</form>';
+
+	return true;
+}
+?>
Index: moodle/mod/quiz/omranswers.php
--- moodle/mod/quiz/omranswers.php No Base Revision
+++ moodle/mod/quiz/omranswers.php Locally New
@@ -0,0 +1,616 @@
+<?php
+/**
+ * This page prints a form for uploading offline attempt data which was obtained after scanning the OMR sheets and processess it.
+ * Analysis of offline attempt data is also done to detect problems with the student records like-
+ * Missing roll number, invalid booklet number, invalid student etc.
+ * Accordingly diagnostics are shown.
+ *
+ * @author Harmeet Saini
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package quiz
+ */
+
+require_once("../../config.php");
+require_once($CFG->dirroot.'/mod/quiz/editlib.php');
+require_once("omranswers_form.php");
+require_once($CFG->libdir . '/uploadlib.php');
+require_once("locallib.php");
+require_once($CFG->dirroot.'/lib/questionlib.php');
+
+$id   = optional_param('cmid', 0, PARAM_INT); // course module id not quiz id
+$thispageurl="$CFG->wwwroot/mod/quiz/omranswers.php?cmid=$id";
+
+if (! $cm = get_coursemodule_from_id('quiz', $id)) {
+	error("There is no coursemodule with id $id");
+}
+
+if (! $course = get_record("course", "id", $cm->course)) {
+	error("Course is misconfigured");
+}
+
+if (! $quiz = get_record("quiz", "id", $cm->instance)) {
+	error("The quiz with id $cm->instance corresponding to this coursemodule $id is missing");
+}
+
+if (! $omrquiz = get_record("omrquiz", "quizid", $cm->instance)) {
+	error("The specified omrquiz does not exist");
+}
+
+if(($omrquiz->bookletcount==0)){
+	redirect("$CFG->wwwroot/mod/quiz/omruploadconfig.php?cmid=$id", "Upload configuration file first..",1);
+}
+else if(!record_exists('omrquiz_booklet', 'omrquizid', $omrquiz->id)){
+	redirect("$CFG->wwwroot/mod/quiz/omr.php?cmid=$id", "Enter booklet information first..",1);
+}
+
+require_login($course->id, false, $cm);
+
+// remove if its not really required
+make_upload_directory("$COURSE->id"); // it creates a directory in files area with its name as the value of the course id
+//make_upload_directory("./$quiz->name");
+
+$navigation = build_navigation(get_string('upload_answers','quiz'), $cm);    //edited by Jalpa
+print_header_simple(get_string('upload_answers','quiz'), '', $navigation, "", "", true, "");   //edited by Jalpa
+$currenttab = 'omr';
+$mode = 'answers';
+include('tabs.php');
+
+$displayform=true;
+$import_form = new answers_import_form($thispageurl);
+
+$viewtype=optional_param('diagnostics',"record", PARAM_CLEAN);
+$response=optional_param('response',NULL,PARAM_CLEAN);
+
+if(!$form = $import_form->get_data() ){
+	if(!optional_param('change',0,PARAM_CLEAN) and !optional_param('continue',0,PARAM_CLEAN) and !optional_param('yes',0,PARAM_CLEAN)){
+		if($omrquiz_response=get_records('omrquiz_answers', 'omrquizid', $omrquiz->id, $sort='id')){
+			$displayform=false;
+			$tempincorrectrecords=array();
+			diagnosticsWrapper($omrquiz_response,$viewtype, $thispageurl, $id);
+		}
+	}
+}
+
+if(optional_param("yes", NULL, PARAM_CLEAN) && $response){
+	//$response=stripslashes($response);   //this is to get the data as it is as it was sent coz while sending the data php itself added backslashes in front of double quotes..
+	//print_r($response);
+	//echo"unserialised:<br>";
+	$response=unserialize(urldecode(stripslashes($response)));
+	if(!$response){
+		error("problem in unserializing serialized string array");
+	}
+	$displayform=false;
+	set_answers($quiz,$response,$omrquiz,$cm->id,$course->id,true);
+
+	//redirect($thispageurl);
+}
+
+if($displayform){
+	if ($import_form->is_cancelled()){
+		redirect($thispageurl);
+	}
+	if($form){
+		// file checks out ok
+		$fileisgood = false;
+		if (!empty($form->choosefile)) {
+			$importfile = "{$CFG->dataroot}/{$COURSE->id}/{$form->choosefile}";
+			$realfilename = $form->choosefile;
+			if (file_exists($importfile)) {
+				$fileisgood = true;
+			}
+			else {
+				print_error('uploadproblem', 'moodle', $form->choosefile);
+			}
+		}
+		else {
+			$realfilename = $import_form->get_importfile_realname();
+			if (!$importfile = $import_form->get_importfile_name()) {
+				print_error('uploadproblem', 'moodle');
+			}
+			else {
+				$fileisgood = true;
+			}
+		}
+		if ($fileisgood){
+			if (ansimportprocess($quiz,$importfile,$omrquiz,$cm->id,$course->id)){
+				print_error('importerror', 'quiz', $thispageurl->out());
+			}
+		}
+		// to store the attempts file in files area.
+		$import_form->_upload_manager->config->deleteothers=false;	//this is to avoid deleting other files in the file area
+		$import_form->_upload_manager->config->handlecollisions=true;	//this is to rename the file if a file with this name already exists
+		$import_form->_upload_manager->process_file_uploads("{$CFG->dataroot}/{$COURSE->id}/{$quiz->name}/answers/");
+
+		if(!$omrquiz_response=get_records('omrquiz_answers', 'omrquizid', $omrquiz->id, $sort='id')){
+			error("Could not get the answers information from db");
+		}
+	}
+	else{
+		print_heading_with_help(get_string('answersheading','quiz'),'omranswers','quiz',NULL,false);   //edited by Jalpa
+		$import_form->display();
+	}
+}
+
+print_footer($course);
+
+// Functions.........
+function ansimportprocess($quiz,$importfile,$omrquiz,$cmid,$courseid) {
+	if (! $lines = readomrdata($importfile)) {
+		notify( get_string('cannotread','quiz'));
+		return false;
+	}
+	foreach($lines as $line) {
+		$response[]=$line;
+	}
+	set_answers($quiz,$response,$omrquiz,$cmid,$courseid);
+}
+
+function readomrdata($filename) { //similar function is also present in question/format.php
+	if (is_readable($filename)) {
+		$filearray = file($filename);
+		/// Check for Macintosh OS line returns (ie file on one line), and fix
+		if (ereg("\r", $filearray[0]) AND !ereg("\n", $filearray[0])) {
+			return explode("\r", $filearray[0]);
+		}
+		else {
+			return $filearray;
+		}
+	}
+	return false;
+}
+
+// in future this function can be specific to the each omr sheet format.i.e for each format there will be a function like this.
+function set_answers($quiz,$response,$omrquiz,$cmid,$courseid, $reupload=false){
+	//$omrquiz_response= new object();
+	$omrquizid=$omrquiz->id;
+	$rollnoposition=$omrquiz->rollnoposition;
+	$rollnolength=$omrquiz->rollnolength;
+	$bookletposition=$omrquiz->bookletposition;
+	$ansposition=$omrquiz->ansposition;
+	$bookletlength=$omrquiz->bookletlength;
+
+	$rollnumbers=array();			// array for all the roll numbers, it will be indexed by line number of the record being processed.
+	$duplicaterollnos=array();		// it will be indexed by line number of the record being processed.
+	$errormessages=array();			// it will be indexed by line number of the record being processed.
+	$omrquiz_response=new object();
+	$omrquizresponsearray=array();	// Array of all the responses that will be fed in database.it will be indexed by line number of the record being processed.
+
+	$questionscount=count(explode(',',$quiz->questions))-1;			//note no. of questions are calculated from original quiz.
+	if(!$omrquiz_response=get_records('omrquiz_answers', 'omrquizid', $omrquizid, $sort='id')){
+		foreach($response as $key=>$value){
+			$linenumber=$key+1;
+			$roll=trim(substr($value,$rollnoposition-1,$rollnolength));
+			$bookletno=trim(substr($value,$bookletposition-1,$bookletlength));
+			$name=trim(substr($value,$rollnolength,($bookletposition)-($rollnolength+1)));
+			$answer=substr($value,$ansposition-1,$questionscount);
+			$omrquiz_response->omrquizid= $omrquizid;
+			$omrquiz_response->bookletno=$bookletno;
+			$omrquiz_response->rollno=$roll;
+			$omrquiz_response->name=$name;
+			$omrquiz_response->answer=$answer;
+
+			if(!($errormessages[$linenumber]=validateomrinput($omrquiz_response,$key, $omrquizid,$courseid))){
+				unset($errormessages[$linenumber]);
+
+			}
+			if(!in_array($omrquiz_response->rollno,$duplicaterollnos) && $omrquiz_response->rollno!=""){
+				if(in_array($omrquiz_response->rollno,$rollnumbers)){
+					$error="duplicate roll number";
+					$duplicaterollnos[$linenumber]=$omrquiz_response->rollno;
+				}
+			}
+			$rollnumbers[$linenumber]=$omrquiz_response->rollno;
+
+			if(isset($error)){
+				$errormessages[$linenumber][]=$error;
+				$omrquiz_response->valid=0;
+				unset($error);
+			}else{
+				$omrquiz_response->valid=1;
+			}
+				
+			if(!($errormessages[$linenumber])){
+				$omrquiz_response->valid=1;
+			}
+			else{
+				$omrquiz_response->valid=0;
+			}
+			$omrquizresponsearray[$linenumber]=$omrquiz_response;
+			unset($omrquiz_response);
+		}
+
+		foreach($rollnumbers as $key=>$value){
+			foreach($duplicaterollnos as $dupkey=>$dupvalue){
+				if($dupvalue==$value and !isset($duplicaterollnos[$key])){
+					$duplicaterollnos[$key]=$dupvalue;
+					$error="duplicate roll number";
+					$errormessages[$key][]=$error;
+					$omrquizresponsearray[$key]->valid=0;
+					//set_field('omrquiz_answers', 'valid', 0, 'omrquizid', $omrquiz->id, 'rollno', $dupvalue);
+				}
+			}
+		}
+
+		$keystosort=array();
+		foreach($omrquizresponsearray as $key=>$value){
+			$keystosort[]=$key;
+		}
+		sort($keystosort);
+		foreach($keystosort as $key=>$value){
+			$temp[$value]=$omrquizresponsearray[$value];
+		}
+		$omrquizresponsearray=$temp;
+		unset($keystosort);
+		unset($temp);
+		//sorting errormessages by line numbers
+		$keystosort=array();
+		foreach($errormessages as $key=>$value){
+			$keystosort[]=$key;
+		}
+		sort($keystosort);
+
+		foreach($keystosort as $key=>$value){
+			$temp[$value]=$errormessages[$value];
+		}
+		$errormessages=$temp;
+		unset($key);
+
+		// now merge error messages with omr responses...
+		foreach($omrquizresponsearray as $lineno => $resp){
+			if(!$errormessages[$lineno]){
+				continue;
+			}else{
+				$lineerrors=$errormessages[$lineno];
+				foreach($lineerrors as $key => $error ){
+					$finalerror[]=$error;
+				}
+				if(count($finalerror)>1){
+					$finalerror=array_unique($finalerror);
+					$finalerror= implode(',', $finalerror);
+				}else{
+					$finalerror=$finalerror[0];
+				}
+				$omrquizresponsearray[$lineno]->problem=$finalerror;
+				unset($finalerror);
+			}
+		}
+		// now storing all the records in database...
+		foreach($omrquizresponsearray as $key => $value){
+			if(!insert_record('omrquiz_answers', $value, $returnid=false, $primarykey='id')){
+				error("could not insert omrbooklet data in table omrquiz_booklet");
+			}
+		}
+		diagnosticsWrapper($omrquizresponsearray,'record','',$cmid);
+	}
+	else{
+		//Multiple Uploads
+		if(!optional_param('yes',NULL, PARAM_CLEAN) && !$reupload){
+			$pass=urlencode(serialize($response));
+
+			print_simple_box_start('center', '60%', '#FFAAAA', 20, 'noticebox');
+			notify("All the attempts for this omr quiz will be deleted..");
+			print_heading("Are you sure you want to reupload the answers?");
+			echo'<form name="reupload" method="post" action="omranswers.php?cmid='.$cmid.'">'; // action=\"omranswers.php?cmid=$cmid\">
+			echo'<input type="hidden" name="response" value='.$pass.' >';
+			echo'<input type="submit" name="yes" value="yes" >';
+			echo'<input type="button" value="no" onclick="javascript:history.go(-2);" >';
+			print_simple_box_end();
+			print_footer();
+			exit;
+		}
+		// deleting attempts..
+		$context = get_context_instance(CONTEXT_MODULE, $cmid);
+		require_capability('mod/quiz:deleteattempts', $context);
+		$attemptids= get_records('quiz_attempts', 'quiz', $quiz->id, 'id', 'id');
+		//if(isset($attemptids) && $attemptids!=''){
+		if($attemptids){
+			foreach($attemptids as $attemptid=>$value) {
+				add_to_log($courseid, 'quiz', 'delete attempt', 'report.php?id=' . $cmid,
+				$attemptid, $cmid);
+				quiz_delete_attempt($attemptid, $quiz);
+			}
+		}
+		// deleting offline answer data
+		delete_records('omrquiz_answers', 'omrquizid', $omrquizid);
+		// reuploading...
+		set_answers($quiz,$response,$omrquiz,$cmid,$courseid);
+	}
+}
+
+function validateomrinput($omrquiz_response, $key, $omrquizid, $courseid){
+	$linenumber=$key+1;
+	$error=array();
+	if(!isset($omrquiz_response->bookletno)){
+		$error[]="booklet number not present";
+	}
+	if(!isset($omrquiz_response->rollno)){
+		$error[]="roll number not present";
+	}
+	if(!isset($omrquiz_response->answer)){
+		$error[]="answer string not present";
+	}
+	if(empty($omrquiz_response->bookletno)){
+		$error[]="booklet number is empty";
+	}
+	if($omrquiz_response->bookletno!=""){
+		if(!is_numeric($omrquiz_response->bookletno)){
+			$error[]="booklet number not numeric";
+		}
+	}
+	if(empty($omrquiz_response->rollno)){
+		$error[]="roll number is empty";
+	}
+	if($omrquiz_response->rollno!=""){
+		//check if student exists
+		if(!record_exists('user', 'username', $omrquiz_response->rollno)){
+			$error[]="invalid user";
+		}
+		//check if student is enrolled for this course
+		if (!$context = get_context_instance(CONTEXT_COURSE, $courseid)) {
+			print_error('nocontext');
+		}
+		$userid= get_field('user', 'id' ,'username',$omrquiz_response->rollno );
+		if(!record_exists('role_assignments', 'contextid', $context->id, 'userid', $userid)){
+			$error[]="invalid user";
+		}
+	}
+
+	if(empty($omrquiz_response->answer)){
+		$error[]="answer string is empty";
+	}
+	$omrquiz_booklets=get_records('omrquiz_booklet', 'omrquizid', $omrquizid, $sort='id');
+	//this function is here for the time being..shud not remain here as it will be executed for each line in input file...which is not necessary
+	foreach($omrquiz_booklets as $value){
+		$booklet[]=$value->bookletno;
+	}
+	if($omrquiz_response->bookletno != ""){
+		if(!in_array($omrquiz_response->bookletno,$booklet)){
+			$error[]="invalid booklet";
+		}
+	}
+	if($error){
+		return $error;
+	}else{
+		return false;
+	}
+}
+
+function showdiagnostics($omrquiz_response, $viewtype="record"){
+	if($viewtype == "record"){
+		$count=1;
+		echo"<table width =100%>";
+		echo'<tr>';                                    //edited by Jalpa  (All echo <TD> statement)
+		echo'<td width=06% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('lineno','quiz').'</b></td></td></tr></table></td>';
+		echo'<td width=25% align=left><table width =100%><tr><td width =20%><td align=left><b>'.get_string('name','quiz').'</b></td></td></tr></table></td>';
+		echo'<td width=15% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('rollno','quiz').'</b></td></td></tr></table></td>';
+		echo'<td width=10% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('bookletno','quiz').'</b></td></td></tr></table></td>';
+		echo'<td width=54% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('diagnostics','quiz').'</b></td></td></tr></table></td>';
+		echo'</tr>';
+
+		foreach($omrquiz_response as $key=>$value){
+			if(!$value->valid){
+				if(is_null($value->problem)){
+					$value->problem="invalid user";
+				}
+				echo"<tr>";
+				echo'<td width=06% align=left><table width =100%><tr><td width =20%><td align=left>  '.$count.'</td></td></tr></table></td> ';
+				echo'<td width=25% align=left><table width =100%><tr><td width =02%><td align=left>  '.$value->name.'</td></td></tr></table></td> ';
+				echo'<td width=15% align=left><table width =100%><tr><td width =10%><td align=left>  '.$value->rollno.'</td></td></tr></table></td> ';
+				echo'<td width=10% align=left><table width =100%><tr><td width =20%><td align=left>  '.$value->bookletno.'</td></td></tr></table></td> ';
+				echo'<td width=54% align=left><table width =100%><tr><td width =02%><td align=left>  '.$value->problem.'</td></td></tr></table></td> ';
+				echo'</tr>';
+			}
+			$count++;
+		}
+		echo"</table>";
+	}else if($viewtype == "category"){
+		$invalidrollno=array();
+		$count=1;
+		foreach($omrquiz_response as $key => $value){
+			$allrecords[$count-1]=$value;
+			if(!$value->valid){
+				if(is_null($value->problem)){
+					$errormessages[$count]=array("invalid user");
+				}else{
+					$errormessages[$count]=array_unique(explode(',', $value->problem));
+				}
+			}
+			$count++;
+		}
+		// now we have to categorize errors
+		// there will be three categories
+		//1. invalid booklet
+		//2. invalid roll no
+		//3. duplicate roll numbers
+		$invalidbooklet=array();
+		$duplicates=array();
+		foreach($errormessages as $key=>$value){
+			$temperror=$value;//explode(',',$value);
+			foreach($temperror as $tempkey=>$tempvalue){
+				if(($tempvalue == "booklet number not present") || ($tempvalue == "booklet number is empty") || ($tempvalue == "booklet number not numeric") || ($tempvalue == "invalid booklet")){
+					$invalidbooklet[]=$key;
+				}
+				if(($tempvalue=="roll number not present") || ($tempvalue=="roll number is empty") ||($tempvalue=="invalid user") ){
+					$invalidrollno[]=$key;
+				}
+				if($tempvalue=="duplicate roll number"){
+					$duplicates[]=$key;
+				}
+			}
+		}
+		if($invalidbooklet){
+			notify("Invalid booklet number");
+			echo"<table width =100%>";
+			echo'<tr>';                                 //edited by Jalpa  (All echo <TD> statement)
+			echo'<td width=10% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('lineno','quiz').'</b></td></td></tr></table></td>';
+			echo'<td width=25% align=left><table width =100%><tr><td width =20%><td align=left><b>'.get_string('name','quiz').'</b></td></td></tr></table></td>';
+			echo'<td width=20% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('rollno','quiz').'</b></td></td></tr></table></td>';
+			echo'<td width=15% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('bookletno','quiz').'</b></td></td></tr></table></td>';
+			echo'<td width=30% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('answer_str','quiz').'</b></td></td></tr></table></td>';
+			echo'</tr>';
+
+			$invalidbooklet=array_unique($invalidbooklet);
+			foreach($invalidbooklet as $key=>$invalid){
+				$z=$invalid-1;
+				$k=$key+1;
+				echo"<tr>";
+				echo'<td width=10% align=left><table width =100%><tr><td width =20%><td align=left>  '.$invalid.'</td></td></tr></table></td> ';
+				echo'<td width=25% align=left><table width =100%><tr><td width =02%><td align=left>  '.$allrecords[$z]->name.'</td></td></tr></table></td> ';
+				echo'<td width=20% align=left><table width =100%><tr><td width =10%><td align=left>  '.$allrecords[$z]->rollno.'</td></td></tr></table></td> ';
+				echo'<td width=15% align=left><table width =100%><tr><td width =20%><td align=left>  '.$allrecords[$z]->bookletno.'</td></td></tr></table></td> ';
+				echo'<td width=30% align=left><table width =100%><tr><td width =02%><td align=left>  '.$allrecords[$z]->answer.'</td></td></tr></table></td> ';
+				echo'</tr>';
+			}
+			echo"</table>";
+			echo"<br>";
+		}
+
+		if($invalidrollno){
+			notify("Invalid roll number");
+			echo"<table width =100%>";
+			echo'<tr>';                                          //edited by Jalpa  (All echo <TD> statement)
+			echo'<td width=10% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('lineno','quiz').'</b></td></td></tr></table></td>';
+			echo'<td width=25% align=left><table width =100%><tr><td width =20%><td align=left><b>'.get_string('name','quiz').'</b></td></td></tr></table></td>';
+			echo'<td width=20% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('rollno','quiz').'</b></td></td></tr></table></td>';
+			echo'<td width=15% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('bookletno','quiz').'</b></td></td></tr></table></td>';
+			echo'<td width=30% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('answer_str','quiz').'</b></td></td></tr></table></td>';
+			echo'</tr>';
+			array_unique($invalidrollno);
+			foreach($invalidrollno as $key=>$invalid){
+				$z=$invalid-1;
+				$k=$key+1;
+				echo"<tr>";
+				echo'<td width=10% align=left><table width =100%><tr><td width =20%><td align=left>  '.$invalid.'</td></td></tr></table></td> ';
+				echo'<td width=25% align=left><table width =100%><tr><td width =02%><td align=left>  '.$allrecords[$z]->name.'</td></td></tr></table></td> ';
+				echo'<td width=20% align=left><table width =100%><tr><td width =10%><td align=left>  '.$allrecords[$z]->rollno.'</td></td></tr></table></td> ';
+				echo'<td width=15% align=left><table width =100%><tr><td width =20%><td align=left>  '.$allrecords[$z]->bookletno.'</td></td></tr></table></td> ';
+				echo'<td width=30% align=left><table width =100%><tr><td width =02%><td align=left>  '.$allrecords[$z]->answer.'</td></td></tr></table></td> ';
+				echo'</tr>';
+			}
+			echo"</table>";
+			echo"<br>";
+		}
+
+		if($duplicates){
+			notify("Duplicate roll number");
+			echo"<table width =100%>";
+			echo'<tr>';                                   //edited by Jalpa  (All echo <TD> statement)
+			echo'<td width=10% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('lineno','quiz').'</b></td></td></tr></table></td>';
+			echo'<td width=25% align=left><table width =100%><tr><td width =20%><td align=left><b>'.get_string('name','quiz').'</b></td></td></tr></table></td>';
+			echo'<td width=20% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('rollno','quiz').'</b></td></td></tr></table></td>';
+			echo'<td width=15% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('bookletno','quiz').'</b></td></td></tr></table></td>';
+			echo'<td width=30% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('answer_str','quiz').'</b></td></td></tr></table></td>';
+			echo'</tr>';
+			array_unique($duplicates);
+			foreach($duplicates as $key=>$invalid){
+				$z=$invalid-1;
+				$k=$key+1;
+				echo"<tr>";
+				echo'<td width=10% align=left><table width =100%><tr><td width =20%><td align=left>  '.$invalid.'</td></td></tr></table></td> ';
+				echo'<td width=25% align=left><table width =100%><tr><td width =02%><td align=left>  '.$allrecords[$z]->name.'</td></td></tr></table></td> ';
+				echo'<td width=20% align=left><table width =100%><tr><td width =10%><td align=left>  '.$allrecords[$z]->rollno.'</td></td></tr></table></td> ';
+				echo'<td width=15% align=left><table width =100%><tr><td width =20%><td align=left>  '.$allrecords[$z]->bookletno.'</td></td></tr></table></td> ';
+				echo'<td width=30% align=left><table width =100%><tr><td width =02%><td align=left>  '.$allrecords[$z]->answer.'</td></td></tr></table></td> ';
+				echo'</tr>';
+			}
+			echo"</table>";
+			echo"<br><br>";
+		}
+	}else {
+		error("invalid select field. this should not happen");
+	}
+}
+
+function diagnosticsWrapper($omrquiz_response, $viewtype, $thispageurl='', $cmid){
+
+	Global $CFG;
+	print_box_start();
+	$errorexists=false;
+	foreach($omrquiz_response as $key=>$value){
+		if(!$value->valid){
+			$errorexists=true;
+			break;
+		}
+	}
+	if($errorexists)	{
+		//code to show diagnostics    // create a select element to have two options 1. record wise and 2. category wise
+		echo "<form name=\"showform\" method=\"post\" action=\"omranswers.php?cmid=$cmid\">";
+		echo'<table width=100%>';
+		echo'<tr>';
+		echo'<td width=30%></td>';
+		echo'<td width=30%></td>';
+		echo'<td width=30%>';
+		
+		echo'<b>'.get_string('diagnostics','quiz').'</b>';   //edited by Jalpa  
+		echo"<a onclick=\"this.target='popup'; return openpopup('/help.php?module=quiz&file=omrdiagnostics.html&forcelang=', 'popup', 'menubar=0,location=0,scrollbars,resizable,width=500,height=400', 0);\" href=\"".$CFG->wwwroot."/help.php?module=quiz&file=omrdiagnostics.html&forcelang=\" title=\"Help with Diagnosis (new window)\"><img src=\"".$CFG->wwwroot."/pix/help.gif\" alt=\"Help with Daignosis (new window)\" class=\"iconhelp\"/></a>";
+
+		echo'<select  name=diagnostics>';
+		if($viewtype == "category"){
+			echo'<option value="category">category wise</option> ';
+			echo'<option value="record">record wise</option> ';
+		}else{
+			echo'<option value="record">record wise</option> ';
+			echo'<option value="category">category wise</option> ';
+		}
+
+		echo'</select>';
+		echo'<input type="submit" name="show" value="show" />';
+		echo'</td>';
+		echo'</tr>';
+		echo'</table>';
+		echo'</form>';
+		echo"<br>";
+
+		showdiagnostics($omrquiz_response,$viewtype);
+	}
+
+	else{//No problem found with uploaded records, these records are shown below.
+		notify('No problem found with uploaded records, these records are shown below');
+		//going to show all the records(records must be correct)
+		$count=1;
+		echo"<table width =100%>";
+		echo'<tr>';                                         //edited by Jalpa  (All echo <TD> statement)
+		echo'<td width=06% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('lineno','quiz').'</b></td></td></tr></table></td>';
+		echo'<td width=25% align=left><table width =100%><tr><td width =20%><td align=left><b>'.get_string('name','quiz').'</b></td></td></tr></table></td>';
+		echo'<td width=15% align=left><table width =100%><tr><td width =02%><td align=left><b> &nbsp &nbsp'.get_string('rollno','quiz').'</b></td></td></tr></table></td>';
+		echo'<td width=10% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('bookletno','quiz').'</b></td></td></tr></table></td>';
+		echo'<td width=54% align=left><table width =100%><tr><td width =02%><td align=left><b> &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp '.get_string('answer_str','quiz').'</b></td></td></tr></table></td>';
+		echo'</tr>';
+
+		foreach($omrquiz_response as $key=>$value){
+			if($value->valid){
+				echo"<tr>";
+				echo'<td width=06% align=left><table width =100%><tr><td width =20%><td align=left>  '.$count.'</td></td></tr></table></td> ';
+				echo'<td width=25% align=left><table width =100%><tr><td width =02%><td align=left>  '.$value->name.'</td></td></tr></table></td> ';
+				echo'<td width=15% align=left><table width =100%><tr><td width =10%><td align=left>  '.$value->rollno.'</td></td></tr></table></td> ';
+				echo'<td width=10% align=left><table width =100%><tr><td width =20%><td align=left>  '.$value->bookletno.'</td></td></tr></table></td> ';
+				echo'<td width=54% align=left><table width =100%><tr><td width =02%><td align=left>  '.$value->answer.'</td></td></tr></table></td> ';
+				echo'</tr>';
+			}
+			$count++;
+		}
+		echo'</table>';
+	}
+	echo '<br>';
+	echo'<table>';
+	echo '<tr>';
+	echo '<td width = "35%"> </td>';
+	echo '<td width = "15%" align="right">';
+	//for displaying change button
+	echo "<form name=\"changeform\" method=\"post\" action=\"omranswers.php?cmid=$cmid\">";
+	echo'<input type="submit" value="change" name="change" />';
+	echo'</form>';
+	echo '</td>';
+	echo '<td width = "15%" align="left">';
+	//for displaying "process attempts" button
+	echo "<form name=\"continueform\" method=\"post\" action=\"omrevaluate.php?cmid=$cmid\">";
+	echo'<center><input type="submit" name="continue" value="process attempts" /></center>';
+	echo'</form>';
+	echo '</td>';
+	echo '<td width = "35%"> </td>';
+	echo '</tr>';
+	echo '</table>';
+	echo'<br>';
+	print_box_end();
+}
+?>
Index: moodle/mod/quiz/omranswers_form.php
--- moodle/mod/quiz/omranswers_form.php No Base Revision
+++ moodle/mod/quiz/omranswers_form.php Locally New
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Form for uploading offline attempt data.
+ *
+ * @author Harmeet Saini
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package quiz
+ */
+
+require_once($CFG->libdir.'/formslib.php');
+
+class answers_import_form extends moodleform {
+
+    function definition() {
+        global $COURSE;
+        $mform    =& $this->_form;
+       // $contexts   = $this->_customdata['contexts'];
+        
+//--------------------------------------------------------------------------------
+        $mform->addElement('header', 'importfileupload', get_string('importfileupload','quiz'));
+
+        $this->set_upload_manager(new upload_manager('newfile', true, false, $COURSE, false, 0, false, true, false));
+        $mform->addElement('file', 'newfile', get_string('upload'));
+//--------------------------------------------------------------------------------
+        $mform->addElement('submit', 'submitbutton', get_string('uploadthisfile'));
+
+//--------------------------------------------------------------------------------
+        if (has_capability('moodle/course:managefiles', get_context_instance(CONTEXT_COURSE, $COURSE->id))){
+            $mform->addElement('header', 'importfilearea', get_string('importfilearea','quiz'));
+
+            $mform->addElement('choosecoursefile', 'choosefile', get_string('choosefile','quiz'));
+//--------------------------------------------------------------------------------
+            $mform->addElement('submit', 'submitbutton', get_string('importfromthisfile','quiz'));
+        }
+//--------------------------------------------------------------------------------
+        $mform->addElement('static', 'dummy', '');
+        $mform->closeHeaderBefore('dummy');
+    }
+    
+    
+function get_importfile_name(){
+        if ($this->is_submitted() and $this->is_validated()) {
+            // return the temporary filename to process
+            return $this->_upload_manager->files['newfile']['tmp_name'];
+        }else{
+            return  NULL;
+        }
+    }
+function get_importfile_realname(){
+        if ($this->is_submitted() and $this->is_validated()) {
+            // return the temporary filename to process
+            return $this->_upload_manager->files['newfile']['name'];
+        }else{
+            return  NULL;
+        }
+    }
+}
+?>
\ No newline at end of file
Index: moodle/mod/quiz/omrattendence.php
--- moodle/mod/quiz/omrattendence.php No Base Revision
+++ moodle/mod/quiz/omrattendence.php Locally New
@@ -0,0 +1,374 @@
+<html>
+		<head>
+		<script type="text/javascript">
+		<!--
+		function alertUser(flag){
+		
+			var ourForm = document.getElementById('attendence');
+			if(flag==1){
+				var r=confirm("Students will be validated against enrollments only..");
+				if(r==true){
+					ourForm.submit();
+				}else{
+					document.getElementById('checkattendence').checked = true;
+				}
+			}
+			else{
+				var r=confirm("Students will be validated against enrollments and attendence list..");
+				if(r==true){
+					ourForm.submit();
+				}else{
+					document.getElementById('checkattendence').checked = false;
+				}
+			}
+		}
+		-->
+		</script>
+		</head>
+<body>
+<?php
+/**
+ * This page prints a form for uploading attendence file for omr quiz and processes it.
+ * Validity of students for a particular quiz is by default checked against course enrollments. 
+ * a student's validity can also be checked against the uploaded attendence list.
+ * So the diagnostics displayed by @ omranswers.php are reflected according to the method of validity choosen here.
+ * 
+ * @author Harmeet Saini, Education Technology Unit, CDAC Mumbai
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package quiz
+ */
+
+require_once("../../config.php");
+require_once("omruploadattendence_form.php");
+require_once($CFG->libdir . '/uploadlib.php');
+require_once("locallib.php");
+
+define('INVALID', 0);
+define('VALIDBY_ENROLMENT', 1);
+define('VALIDBY_ATTENDENCE', 2);
+
+
+$id   = optional_param('cmid', 0, PARAM_INT);     // course module id not quiz id
+$thispageurl="$CFG->wwwroot/mod/quiz/omrattendence.php?cmid=$id";
+
+if (! $cm = get_coursemodule_from_id('quiz', $id)) {
+	error("There is no coursemodule with id $id");
+}
+
+if (! $course = get_record("course", "id", $cm->course)) {
+	error("Course is misconfigured");
+}
+
+if (! $quiz = get_record("quiz", "id", $cm->instance)) {
+	error("The quiz with id $cm->instance corresponding to this coursemodule $id is missing");
+}
+
+if (! $omrquiz = get_record("omrquiz", "quizid", $cm->instance)) {
+	error("The specified omrquiz does not exist");
+}
+
+require_login($course->id, false, $cm);
+
+$navigation = build_navigation(get_string('upload_quiz_attendence','quiz'), $cm);    //edited by Jalpa
+print_header_simple(get_string('upload_quiz_attendence','quiz'), '', $navigation, "", "", true, "");   //edited by Jalpa   
+$currenttab = 'omr';
+$mode = 'attendence';
+include('tabs.php');
+
+$displayform=true;
+$displayattendence=true;
+$import_form = new omrattendence_import_form($thispageurl);
+
+if(optional_param('continue',NULL, PARAM_CLEAN)){
+	$displayform=false;
+	if(record_exists('omrquiz_answers','omrquizid',$omrquiz->id)){
+		$displayattendence=false;
+		print_simple_box_start('center', '60%', '', 20,'noticebox');
+		notify(get_string('validate_against_attendence', 'quiz'));	//edited by hameet
+		echo'<form name="notice" method="post" action='.$thispageurl.'>';
+		echo'<input type="submit" name="Yes" value="Yes" >';
+		echo'<input type="submit" name="No" value="No" >';
+		//echo'<input type="button" value="no" onclick="javascript:history.go();" >';
+		print_simple_box_end();
+	}else{
+		//redirect("$CFG->wwwroot/mod/quiz/omranswers.php?cmid=$id","Redirecting for answers upload...",-1);
+	}
+	
+}
+
+
+if(optional_param('No',NULL, PARAM_CLEAN)){
+	$displayform=false;
+	//redirect($thispageurl);
+}
+
+if(optional_param('Yes',NULL, PARAM_CLEAN)){
+	check_user_against_attendence($omrquiz->id);
+	$displayform=false;
+	//redirect($thispageurl);
+}
+if(optional_param('checkattendence',-1,PARAM_CLEAN) == 1){
+	check_user_against_attendence($omrquiz->id);
+}
+if(optional_param('checkattendence',-1,PARAM_CLEAN) == 0){
+	check_user_against_enrollments($omrquiz->id);
+}
+
+if(! $form = $import_form->get_data()) {
+	if($omrattendence=get_records('omrquiz_attendence', 'omrquizid',$omrquiz->id)){
+		// && !optional_param('Yes',NULL,PARAM_CLEAN) && !optional_param('No',NULL,PARAM_CLEAN)
+		//&& !optional_param('continue',NULL,PARAM_CLEAN)
+		if(!optional_param('change',0,PARAM_CLEAN)  && $displayattendence){
+		$displayform=false;
+		print_box_start();
+		notify(get_string('attendencelist', quiz));
+		$count=1;
+		foreach($omrattendence as $value){
+			if($count < 10){
+				echo(' '.$count .'  &nbsp &nbsp &nbsp  '.$value->rollno.' <br>');
+				$count++;
+			}
+			else{
+				echo(' '.$count .'   &nbsp &nbsp '.$value->rollno.' <br>');
+				$count++;
+			}			
+		}
+		echo"<br>";
+		if(record_exists('omrquiz_answers','omrquizid',$omrquiz->id)){
+			$valids=get_records('omrquiz_answers', 'omrquizid', $omrquiz->id);	// all the records of an omrquiz
+			$validatedByAttendence=false;
+			foreach($valids as $value){
+				if($value->valid==2){
+					$validatedByAttendence=true;
+					break;
+				}
+			}
+			echo'<form name="attendenceform" method="post" action='.$thispageurl.' id="attendence" >';
+			echo '<input type="hidden" name="checkattendence" value="0" />';
+			echo '<input type="checkbox" name="checkattendence" id="checkattendence" value="1" ';
+		
+			if ($validatedByAttendence) {
+	        	echo 'checked="checked"';
+    		}
+    		echo 'onclick="alertUser('.$validatedByAttendence.');" />';
+    		echo"Check student validity against attendence list";
+    	}
+    	
+		//for displaying change button after displaying already present data.
+		echo "<form name=\"changeform\" method=\"post\" action=\"$thispageurl\">";
+		echo'<center><input type="submit" value="change" name="change" /></center>';
+		echo'</form>';
+		print_box_end();
+	}
+	}
+	
+}
+
+if($displayform){
+	if ($import_form->is_cancelled()){
+		redirect($thispageurl);
+	}
+	if($form) {
+		// file checks out ok
+		$fileisgood = false;
+		if (! empty($form->choosefile)) {
+			$importfile = "{$CFG->dataroot}/{$COURSE->id}/{$form->choosefile}";
+			$realfilename = $form->choosefile;
+			if (file_exists($importfile)) {
+				$fileisgood = true;
+			}
+			else {
+				print_error('uploadproblem', 'moodle', $form->choosefile);
+			}
+		}
+		else {
+			$realfilename = $import_form->get_importfile_realname();
+			if (! $importfile = $import_form->get_importfile_name()) {
+				print_error('uploadproblem', 'moodle');
+			}
+			else {
+				$fileisgood = true;
+			}
+		}
+		if ($fileisgood){
+			if (attendenceimportprocess($quiz,$importfile,$omrquiz->id,$cm->id, $course->id , $thispageurl)){
+				print_error('importerror', 'quiz', $thispageurl->out());
+			}
+		}
+		//for printing continue button after displaying attendence data after first upload of file or when there is data already present
+		echo "<form name=\"continueform\" method=\"post\" action=\"$thispageurl\">";
+		echo'<center><input type="submit" name="continue" value="continue" /></center>';
+		echo'</form>';
+		print_box_end();
+	}
+	else{
+		print_heading_with_help(get_string('attendanceheading','quiz'),'omrattendance','quiz',NULL,false);   //edited by Jalpa
+		$import_form->display();
+	}
+}
+
+print_footer($course);
+
+//------------------------------------------Functions-------------------------------------------
+
+/**
+ * Reads the uploaded attendence file and processes it.
+ * It calls {@link readattendencedata()} for getting the file contents as an array.
+ * calls {@link set_omrquiz()} for setting up the configuration for OMR quiz
+ *
+ * @param Object $quiz
+ * @param String $importfile
+ * @param String $omrquizid
+ * @param String $cmid
+ * @param String $courseid
+ * @param String $thispageurl
+ */
+
+function attendenceimportprocess($quiz,$importfile,$omrquizid,$cmid, $courseid, $thispageurl) {
+	if (! $lines = readattendencedata($importfile)) {
+		notify( get_string('cannotread','quiz') );
+		return false;
+	}
+	if (! $response = trimresponse($lines)) {
+		notify( "some problem occured, no data present" );
+		return false;
+	}
+	set_attendence($quiz,$response,$omrquizid,$cmid,$courseid);
+
+}
+
+/**
+ * reads the contents of a file in an array
+ * @param array $filename
+ * @return array $filearray the array with contents as the whole file, false on failure.
+ */
+function readattendencedata($filename) {
+	if (is_readable($filename)) {
+		$filearray = file($filename);
+		/// Check for Macintosh OS line returns (ie file on one line), and fix
+		if (ereg("\r", $filearray[0]) AND !ereg("\n", $filearray[0])) {
+			return explode("\r", $filearray[0]);
+		}
+		else {
+			return $filearray;
+		}
+	}
+	return false;
+}
+
+/*
+ * Just trims every line in array
+ * @param array   $lines file contents as array
+ * @return array  $response trimmed response
+ */
+function trimresponse($lines) { 
+	foreach($lines as $line) {
+		$line = trim($line);
+		$response[]=$line;
+	}
+	return $response;
+}
+
+/**
+ * Extracts attendence from uploaded file. Stores the information in database and then displays the
+ * attendece information on screen.
+ * Reuploads the OMR attendence if attendence already present
+ *
+ * @param Object  $quiz
+ * @param array   $response The array having the contents of uploaded attendence file
+ * @param String  $omrquizid
+ * @param String  $cmid
+ * @param String  $courseid
+ */
+function set_attendence($quiz, $response, $omrquizid, $cmid, $courseid){
+	$rollnumbers;
+	foreach($response as $value){
+		$rollnumbers[]=$value;
+	}
+	sort($rollnumbers);
+	$omrattendence=new object();
+	$omrattendence->omrquizid=$omrquizid;
+	print_box_start();
+	
+	if( !record_exists('omrquiz_attendence', 'omrquizid', $omrquizid) ){
+		//first time attendece upload
+		foreach($rollnumbers as $value){
+			$omrattendence->rollno=$value;
+			if(!insert_record('omrquiz_attendence', $omrattendence)){
+				error("could not insert record in omr_attendence");
+			}	
+		}
+		notify("Attendence uploaded successfully");
+	}else{
+		// reupload omr attendence
+		delete_records('omrquiz_attendence', 'omrquizid', $omrquizid);
+		foreach($rollnumbers as $value){
+			$omrattendence->rollno=$value;
+			if(!insert_record('omrquiz_attendence', $omrattendence)){
+				error("could not insert record in omr_attendence");
+			}	
+		}
+		notify("Attendence re uploaded successfully");
+		if(record_exists('omrquiz_answers','omrquizid',$omrquizid)){
+			check_user_against_enrollments($omrquizid);
+		}
+		
+	}
+	
+	foreach($rollnumbers as $value){
+			echo"$value<br>";
+	}
+}
+
+/**
+ * Validates the user against uploaded attendence also.
+ * By default the validity of user is checked against the enrollment only. That is 
+ * if the user is enrolled in the course then he/she is valid user for a quiz in that course.
+ *
+ * @param String  $omrquizid
+ */
+function check_user_against_attendence($omrquizid){
+	$attendence=get_records('omrquiz_attendence', 'omrquizid', $omrquizid);
+	foreach($attendence as $value){
+		$attendencelist[]=$value->rollno;
+	}
+	$partialValids=get_records('omrquiz_answers','omrquizid', $omrquizid);
+	foreach($partialValids as $value){
+		if($value->valid ==1 || $value->valid ==2){
+			if(in_array($value->rollno, $attendencelist)){
+				$value->valid=2;
+				update_record('omrquiz_answers', $value);
+			}else{
+				$value->valid=0;
+				update_record('omrquiz_answers', $value);
+			}
+		}
+	}
+	
+}
+
+/**
+ * If the user validity is already done against attendence in addition to validity against enrollments
+ * then this function nullifies the validity against attendence and
+ * validates the user against enrollment only.
+ * 
+ * @param String  $omrquizid
+ */
+function check_user_against_enrollments($omrquizid){
+	$attendence=get_records('omrquiz_attendence', 'omrquizid', $omrquizid);
+	$invalids=get_records('omrquiz_answers','omrquizid', $omrquizid);
+	foreach($invalids as $value){
+		if($value->valid == 0 && is_null($value->problem)){
+			$value->valid=1;
+			update_record('omrquiz_answers', $value);
+		}else if($value->valid == 2){
+			$value->valid=1;
+			update_record('omrquiz_answers', $value);
+		}
+	}
+}
+
+?>
+
+</body>
+</html>
Index: moodle/mod/quiz/omrevaluate.php
--- moodle/mod/quiz/omrevaluate.php No Base Revision
+++ moodle/mod/quiz/omrevaluate.php Locally New
@@ -0,0 +1,335 @@
+<?php
+/**
+ * This page displays both the correct records from the offline attempt data which are going to be evaluated
+ * and incorrect records which are not going to be processed.
+ * There is a button "process results" for evaluating the correct records.
+ * The offline attempts are processed just the same way as online attempts are processed and evaluated.
+ * So the offline attempts can be seen online the same way the normal Quiz attempts are seen.
+ * further, results are also available in results tab and item analysis can also be performed on these results.
+ *
+ * @author Harmeet Saini
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package quiz
+ */
+require_once("../../config.php");
+require_once($CFG->dirroot.'/mod/quiz/editlib.php');
+require_once("omranswers_form.php");
+require_once($CFG->libdir . '/uploadlib.php');
+require_once("locallib.php");
+require_once($CFG->dirroot.'/lib/questionlib.php');
+
+$id   = optional_param('cmid', 0, PARAM_INT); // course module id not quiz id
+$thispageurl="$CFG->wwwroot/mod/quiz/omrevaluate.php?cmid=$id";
+
+if (! $cm = get_coursemodule_from_id('quiz', $id)) {
+	error("There is no coursemodule with id $id");
+}
+if (! $course = get_record("course", "id", $cm->course)) {
+	error("Course is misconfigured");
+}
+if (! $quiz = get_record("quiz", "id", $cm->instance)) {
+	error("The quiz with id $cm->instance corresponding to this coursemodule $id is missing");
+}
+if (! $omrquiz = get_record("omrquiz", "quizid", $cm->instance)) {
+	error("The specified omrquiz does not exist");
+}
+if(($omrquiz->bookletcount==0)){
+	redirect("$CFG->wwwroot/mod/quiz/omruploadconfig.php?cmid=$id", "Upload configuration file first..",1);
+}
+else if(!record_exists('omrquiz_booklet', 'omrquizid', $omrquiz->id)){
+	redirect("$CFG->wwwroot/mod/quiz/omr.php?cmid=$id", "Enter booklet information first..",1);
+}
+else if(!record_exists('omrquiz_answers', 'omrquizid', $omrquiz->id)){
+	redirect("$CFG->wwwroot/mod/quiz/omranswers.php?cmid=$id", "upload answers first.",1);
+}
+
+require_login($course->id, false, $cm);
+
+$navigation = build_navigation(get_string('evaluate_omr_attempts','quiz'), $cm);     //edited by Jalpa
+print_header_simple(get_string('evaluate_omr_attempts','quiz'), '', $navigation, "", "", true, "");   //edited by Jalpa
+$currenttab = 'omr';
+$mode = 'process';
+include('tabs.php');
+
+if(optional_param('process',null,PARAM_CLEAN)){
+	if($omrquiz_answers=get_records('omrquiz_answers', 'omrquizid', $omrquiz->id, $sort='rollno')){
+		ini_set('max_execution_time', 300);   // this is to set the execution time of this script to 5 minutes othervise all records will not be processed
+		foreach($omrquiz_answers as $key=>$value){
+			//$bookletnoarray[$l]=$value->bookletno;
+			if($value->valid){
+				omrevaluate($quiz,$omrquiz->id,$value->bookletno,$value->rollno,$value->answer, $course->id, $cm->id);
+			}
+		}
+		redirect("$CFG->wwwroot/mod/quiz/report.php?q=$quiz->id",'' , 0);
+	}
+}
+if($omrquiz_response=get_records('omrquiz_answers', 'omrquizid', $omrquiz->id, $sort='id')){
+	$displayform=false;
+	$tempincorrectrecords=array();
+
+	print_heading_with_help(get_string('attemptsheading','quiz'),'omrattempts','quiz',NULL,false);   //edited by Jalpa		
+	print_box_start();
+	$correctrecordexist=false;
+	foreach($omrquiz_response as $key=>$value){
+		if($value->valid){
+			$correctrecordexist=true;
+			break;
+		}
+	}
+	if($correctrecordexist){
+		$noofcorrectrecords=count_records('omrquiz_answers', 'omrquizid', $omrquiz->id, 'valid', 1);
+		if(!$noofcorrectrecords){
+			$noofcorrectrecords=count_records('omrquiz_answers', 'omrquizid', $omrquiz->id, 'valid', 2);
+		}
+		notify(get_string('noofcorrectrecords','quiz',$noofcorrectrecords));  //edited by Jalpa
+
+		echo"<table width =100%>";
+		echo'<tr>';                                  //edited by Jalpa  (All echo <TD> statement)
+		echo'<td width=06% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('lineno','quiz').'</b></td></td></tr></table></td>';     
+		echo'<td width=25% align=left><table width =100%><tr><td width =20%><td align=left><b>'.get_string('name','quiz').'</b></td></td></tr></table></td>';
+		echo'<td width=15% align=left><table width =100%><tr><td width =02%><td align=left><b> &nbsp &nbsp '.get_string('rollno','quiz').'</b></td></td></tr></table></td>';
+		echo'<td width=10% align=left><table width =100%><tr><td width =02%><td align=left><b>'.get_string('bookletno','quiz').'</b></td></td></tr></table></td>';
+		echo'<td width=54% align=left><table width =100%><tr><td width =02%><td align=left><b> &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp &nbsp '.get_string('answer_str','quiz').'</b></td></td></tr></table></td>';
+		echo'</tr>';		
+	}
+	$count=1;
+	foreach($omrquiz_response as $key=>$value){
+		if($value->valid){
+			echo"<tr>";
+			echo'<td width=06% align=left><table width =100%><tr><td width =20%><td align=left>  '.$count.'</td></td></tr></table></td> ';
+			echo'<td width=25% align=left><table width =100%><tr><td width =02%><td align=left>  '.$value->name.'</td></td></tr></table></td> ';
+			echo'<td width=15% align=left><table width =100%><tr><td width =10%><td align=left>  '.$value->rollno.'</td></td></tr></table></td> ';
+			echo'<td width=10% align=left><table width =100%><tr><td width =20%><td align=left>  '.$value->bookletno.'</td></td></tr></table></td> ';
+			echo'<td width=54% align=left><table width =100%><tr><td width =02%><td align=left>  '.$value->answer.'</td></td></tr></table></td> ';
+			echo'</tr>';
+		}else{
+			$tempincorrectrecords[$count]= $value;
+		}
+		$count++;
+	}
+	echo'</table>';
+	echo'<br>';
+	if($tempincorrectrecords){
+		$noofwrongrecords=count_records('omrquiz_answers', 'omrquizid', $omrquiz->id, 'valid', 0);
+		notify(get_string('noofwrongrecords','quiz',$noofwrongrecords));    //edited by Jalpa 
+		echo'<table width=100%>';
+		foreach($tempincorrectrecords as $key => $value){
+			echo"<tr>";
+			echo'<td width=06% align=left><table width =100%><tr><td width =20%><td align=left>  '.$key.'</td></td></tr></table></td> ';
+			echo'<td width=25% align=left><table width =100%><tr><td width =02%><td align=left>  '.$value->name.'</td></td></tr></table></td> ';
+			echo'<td width=15% align=left><table width =100%><tr><td width =10%><td align=left>  '.$value->rollno.'</td></td></tr></table></td> ';
+			echo'<td width=10% align=left><table width =100%><tr><td width =20%><td align=left>  '.$value->bookletno.'</td></td></tr></table></td> ';
+			echo'<td width=54% align=left><table width =100%><tr><td width =02%><td align=left>  '.$value->answer.'</td></td></tr></table></td> ';
+			echo'</tr>';
+		}
+		echo'</table>';
+	}
+}
+echo "<form name=\"myform\" method=\"post\" action=\"omrevaluate.php?cmid=$id\">";
+echo '<fieldset class="invisiblefieldset" style="display: block;">';
+echo "<input type=\"hidden\" name=\"sesskey\" value=\"$USER->sesskey\" />";
+echo '<div class="quizquestionlistcontrols"><input type="submit" name=process value="process results" />';
+// echo '<input type="hidden" name="savechanges" value="save" /></div>';   //for savechanges button to work.
+echo '</fieldset>';
+echo "</form>\n";
+print_box_end();
+print_footer($course);
+
+function omrevaluate($quiz,$omrquizid, $bookletno, $userloginid, $answer,$courseid, $cmid){
+	//initialisation part ....think of it as before submiting the form.....
+	global $CFG;
+	if(!$userid=get_field('user', 'id', 'username', $userloginid)){
+		error('Could not get user information');
+	}
+	//it can be an argument with default value 1. so tht in future if multiple offline attempts are allowed, its value can be taken from omrconfig
+	$attemptnumber=1;  //its not used at present. it can be deleted.
+	$questionlist=get_field('omrquiz_booklet', 'questionsequence', 'omrquizid', $omrquizid, 'bookletno', $bookletno);
+	$attempt = omrquiz_create_attempt($quiz, $userid, $questionlist);
+	if (!$attempt->id = insert_record('quiz_attempts', $attempt)) {
+		error('Could not create new attempt');
+	}
+	add_to_log($courseid, 'quiz', 'attempt',
+	           "review.php?attempt=$attempt->id",
+	       "$quiz->id", $cmid);
+
+	$questionlist=str_replace(',0', '', $questionlist);
+	$sql = "SELECT q.*, i.grade AS maxgrade, i.id AS instance".
+           "  FROM {$CFG->prefix}question q,".
+           "       {$CFG->prefix}quiz_question_instances i".
+           " WHERE i.quiz = '$quiz->id' AND q.id = i.question".
+           "   AND q.id IN ($questionlist)";
+
+	if (!$questions = get_records_sql($sql)) {
+		print_error('noquestionsfound', 'quiz', 'view.php?q='.$quiz->id);
+	}
+	// Load the question type specific information
+	if (!get_question_options($questions)) {
+		error('Could not load question options');
+	}
+	if (!$states = get_question_states($questions, $quiz, $attempt, $lastattemptid)) {
+		error('Could not restore question sessions');
+	}
+	foreach ($questions as $i => $question) {
+		save_question_session($questions[$i], $states[$i]);	
+	}
+
+	// post initialisation....think as after form submission....
+	$finishattempt = 1;
+	$timelimitseconds=get_field('quiz', 'timelimit', 'id', $quiz->id)*60;
+	$attempt->timefinish=$attempt->timestart + $timelimitseconds;
+	$attempt->timemodified=$attempt->timefinish;
+	$answer="$answer";  // quotes are important...
+	$answer=str_split($answer);
+
+	foreach($answer as $key=>$value){
+		switch("$value"){
+			case "A":
+				$answer[$key]=0;
+				break;
+			case "a":
+				$answer[$key]=0;
+				break;
+			case "B":
+				$answer[$key]=1;
+				break;
+			case "b":
+				$answer[$key]=1;
+				break;
+			case "C":
+				$answer[$key]=2;
+				break;
+			case "c":
+				$answer[$key]=2;
+				break;
+			case "D":
+				$answer[$key]=3;
+				break;
+			case "d":
+				$answer[$key]=3;
+				break;
+			case " ":
+				$answer[$key]="";
+				break;
+			default :
+				$answer[$key]="";
+		}
+	}
+	$attemptnumber=1; // or if it is passed as parameter to this fuction then its value can b taken from there
+	$questionids=$questionlist;  // coz in original function name questionid is used...v can change it later
+	$questionidarray = explode(',', $questionids);
+
+	foreach($questionidarray as $index=>$question){
+		if(!$availableoptions=get_records('question_answers', 'question', $question, $sort='', 'id, question')){
+			error('unable to fetch records from question_answers');
+		}
+		foreach($availableoptions as $key => $value){
+			if($question==$value->question){
+				$optionid[$question][]=$key;
+			}
+		}
+		$responses[$question]=$optionid[$question][$answer[$index]];
+	}
+	$responses['timeup']=0;
+	$event=8;    // QUESTION_EVENTCLOSE
+	$actions = question_extract_omrresponses($questions, $responses, $event);
+
+	// Process each question in turn
+	foreach($questionidarray as $i) {
+		if (!isset($actions[$i])) {
+			$actions[$i]->responses = array('' => '');
+			$actions[$i]->event = QUESTION_EVENTOPEN;
+		}
+		$actions[$i]->timestamp = $attempt->timefinish;
+		if (question_process_responses($questions[$i], $states[$i], $actions[$i], $quiz, $attempt)) {
+			save_question_session($questions[$i], $states[$i]);
+		}else {
+			error('could not process the responses');
+		}
+	}
+
+	//now simulate finish the attempt
+	$closequestionlist="$questionlist";
+	$sql = "SELECT q.*, i.grade AS maxgrade, i.id AS instance".
+               "  FROM {$CFG->prefix}question q,".
+               "       {$CFG->prefix}quiz_question_instances i".
+               " WHERE i.quiz = '$quiz->id' AND q.id = i.question".
+               "   AND q.id IN ($closequestionlist)";
+	if (!$closequestions = get_records_sql($sql)) {
+		error('Questions missing');
+	}
+	if (!get_question_options($closequestions)) {
+		error('Could not load question options');
+	}
+	// Restore the question sessions
+	if (!$closestates = get_question_states($closequestions, $quiz, $attempt)) {
+		error('Could not restore question sessions');
+	}
+	foreach($closequestions as $key => $question) {
+		$action->event = QUESTION_EVENTCLOSE;
+		$action->responses = $closestates[$key]->responses;
+		$action->timestamp = $closestates[$key]->timestamp;
+
+		if (question_process_responses($question, $closestates[$key], $action, $quiz, $attempt)) {
+			save_question_session($question, $closestates[$key]);
+		} else {
+			error('could not process responses while closing attempts');
+		}
+	}
+	add_to_log($courseid, 'quiz', 'close attempt',
+	            "review.php?attempt=$attempt->id",
+	       "$quiz->id", $cmid);
+
+	if ($responses || $finishattempt) {
+		if (!update_record('quiz_attempts', $attempt)) {
+			error('Failed to save the current quiz attempt!');
+		}
+		if (($attempt->attempt > 1 || $attempt->timefinish > 0) and !$attempt->preview) {
+			quiz_save_best_grade($quiz,$userid);
+		}
+	}
+	return true;
+}
+
+function omrquiz_create_attempt($quiz, $userid, $questionlist) {
+	global $CFG;
+	// we are not building on last attempt so create a new attempt
+	$attempt->quiz = $quiz->id;
+	$attempt->userid = $userid;
+	$attempt->preview = 0;
+	$attempt->layout = "$questionlist";
+	$timenow = time();
+	$attempt->attempt =1;			//this is hardcoded...attempt number
+	$attempt->sumgrades = 0.0;
+	$attempt->timestart = get_field('quiz', 'timeopen', 'id', $quiz->id);
+	$attempt->timefinish = 0;
+	$attempt->timemodified = $attempt->timestart;
+	$attempt->uniqueid = question_new_attempt_uniqueid();
+	return $attempt;
+}
+
+function question_extract_omrresponses($questions, $formdata, $defaultevent=QUESTION_EVENTSAVE) {
+
+	$time = get_field('quiz', 'timeclose', 'id', $quiz->id);
+	$actions = array();
+	foreach ($formdata as $key => $response) {
+		if($key!="timeup"){		//because last key of the array is "timeup" which we do not need here.
+			$quid=$key;
+			// check if this is a valid id
+			if (!isset($questions[$quid])) {
+				error("this is not a valid question id $quid");
+			}
+			$actions[$quid]->event = $defaultevent;
+				
+			// Update the state with the new response
+			$actions[$quid]->responses[] = $response;
+				
+			// Set the timestamp
+			$actions[$quid]->timestamp = $time;
+		}
+	}
+	foreach ($actions as $quid => $notused) {
+		ksort($actions[$quid]->responses);
+	}
+	return $actions;
+}
+?>
Index: moodle/mod/quiz/omrpreview.php
--- moodle/mod/quiz/omrpreview.php No Base Revision
+++ moodle/mod/quiz/omrpreview.php Locally New
@@ -0,0 +1,103 @@
+<html>
+<title>Preview Quiz</title>
+<body>
+<?php
+
+/**
+ * This page prints the question paper for a particular question paper variant. It can be printed and given for offline exam.
+ *
+ * @author Harmeet Saini
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package quiz
+ */
+require_once("../../config.php");
+require_once($CFG->dirroot.'/mod/quiz/editlib.php');
+
+$cmid=optional_param('cmid',NULL,PARAM_INT);
+$omrquizid=optional_param('omrquizid',NULL,PARAM_INT);
+$bookletid=optional_param('bookletid',NULL,PARAM_INT);
+$bookletno=get_field('omrquiz_booklet', 'bookletno', 'id', $bookletid);
+
+if (! $cm = get_coursemodule_from_id('quiz', $cmid)) {
+	error("There is no coursemodule with id $id");
+}
+if (! $course = get_record("course", "id", $cm->course)) {
+	error("Course is misconfigured");
+}
+if (! $quiz = get_record("quiz", "id", $cm->instance)) {
+	error("The quiz with id $cm->instance corresponding to this coursemodule $id is missing");
+}
+
+require_login($course->id, false, $cm);
+$quizname=$quiz->name;
+$coursename=$course->fullname;
+$coursecategoryname=get_field('course_categories', 'name', 'id', $course->category);
+
+print_omrheader($bookletno,$quiz,$coursename,$coursecategoryname);
+
+$questionseq=get_field('omrquiz_booklet', 'questionsequence', 'omrquizid', $omrquizid, 'id', $bookletid);
+$pagebreakposition=array();
+$questionsequence=explode(',',$questionseq);
+
+foreach($questionsequence as $key=> $value){
+	if($value==0){
+		$pagebreakposition[]=$key;
+		unset($questionsequence[$key]);
+	}
+}
+$subtractfrompagebreak=0;
+$newpagebreakposition=array();
+
+foreach($pagebreakposition as $value){
+	$value=$value-$subtractfrompagebreak;
+	$newpagebreakposition[]=$value;
+	$subtractfrompagebreak++;
+}
+$questionsequence=implode(',',$questionsequence);
+$questionsequence=explode(',',$questionsequence);
+$questionseq=$questionsequence;
+$questioncount=count($questionsequence);
+
+echo'<font face="verdana" size="3">';
+echo'<ol type=1>';
+for($i=0;$i<$questioncount;$i++){
+	foreach($newpagebreakposition as $value){
+		if($i==$value){
+			echo'<DIV style="page-break-after:always"></DIV>';
+		}
+	}
+	$j=$i+1;
+	//echo'Q. '.$j.' ';
+	$questiontext[$i]=get_field('question', 'questiontext', 'id', $questionseq[$i]);
+	$options[$i]=get_records('question_answers', 'question',$questionseq[$i],'id');
+	//echo" ";
+	echo '<font face="verdana"><li> '.$questiontext[$i].' </li></font>';
+
+	echo'<ol type=A>';
+	foreach($options[$i] as $key=>$value){
+		echo'<li>';
+		echo''.$value->answer.'';
+	}
+	echo'</ol> ';
+	echo'<br>';
+}
+echo'</ol>';
+echo'</font>';
+
+function print_omrheader($bookletno,$quiz,$coursename,$coursecategoryname){
+	echo'<h3 align="right">Booklet No: '.$bookletno.'</h3>';
+	echo'<h1 align="center"  > '.$coursecategoryname.' </h1>';
+	echo'<h2 align="center"  > '.$coursename.' </h2>';
+	echo'<h3 align="center"> '.$quiz->name.' </h3><br>';
+	echo'<font face="verdana" size="3">';
+	echo'<table border=0 width=100%>';
+	echo'<tr><td width=20% ></td><td width=50%  ></td><td width=30% align="left"><b>Date:</b> '.date("D, M jS Y",$quiz->timeopen).'</td></tr>';
+	echo'<tr><td width=20% align="left"></td><td width=50%  ></td><td width=30% align="left"><b>Max Marks: </b>'.$quiz->grade.'</td></tr>';
+	echo'<tr><td width=20% align="left"><b>Student ID:</b></td><td width=50%  ></td><td width=30% align="left"><b>Duration: </b>'.$quiz->timelimit.' minutes</td></tr>';
+	echo'</table> <hr>';
+	echo"$quiz->intro <br>";
+	echo'</font>';
+}
+?>
+</body>
+</html>
Index: moodle/mod/quiz/omruploadattendence_form.php
--- moodle/mod/quiz/omruploadattendence_form.php No Base Revision
+++ moodle/mod/quiz/omruploadattendence_form.php Locally New
@@ -0,0 +1,51 @@
+<?php
+require_once($CFG->libdir.'/formslib.php');
+
+//class for creating upload form for OMR quiz attendence upload. It is called from omrattendence.php
+class omrattendence_import_form extends moodleform {
+
+    function definition() {
+        global $COURSE;
+        $mform    =& $this->_form;
+       // $contexts   = $this->_customdata['contexts'];
+        
+//--------------------------------------------------------------------------------
+        $mform->addElement('header', 'importfileupload', get_string('importfileupload','quiz'));
+
+        $this->set_upload_manager(new upload_manager('newfile', true, false, $COURSE, false, 0, false, true, false));
+        $mform->addElement('file', 'newfile', get_string('upload'));
+//--------------------------------------------------------------------------------
+        $mform->addElement('submit', 'submitbutton', get_string('uploadthisfile'));
+
+//--------------------------------------------------------------------------------
+        if (has_capability('moodle/course:managefiles', get_context_instance(CONTEXT_COURSE, $COURSE->id))){
+            $mform->addElement('header', 'importfilearea', get_string('importfilearea','quiz'));
+
+            $mform->addElement('choosecoursefile', 'choosefile', get_string('choosefile','quiz'));
+//--------------------------------------------------------------------------------
+            $mform->addElement('submit', 'submitbutton', get_string('importfromthisfile','quiz'));
+        }
+//--------------------------------------------------------------------------------
+        $mform->addElement('static', 'dummy', '');
+        $mform->closeHeaderBefore('dummy');
+    }
+    
+    
+function get_importfile_name(){
+        if ($this->is_submitted() and $this->is_validated()) {
+            // return the temporary filename to process
+            return $this->_upload_manager->files['newfile']['tmp_name'];
+        }else{
+            return  NULL;
+        }
+    }
+function get_importfile_realname(){
+        if ($this->is_submitted() and $this->is_validated()) {
+            // return the temporary filename to process
+            return $this->_upload_manager->files['newfile']['name'];
+        }else{
+            return  NULL;
+        }
+    }
+}
+?>
\ No newline at end of file
Index: moodle/mod/quiz/omruploadconfig.php
--- moodle/mod/quiz/omruploadconfig.php No Base Revision
+++ moodle/mod/quiz/omruploadconfig.php Locally New
@@ -0,0 +1,356 @@
+<?php
+/**
+ * This page prints a form for uploading configuration file for omr quiz and processes it.
+ *
+ * @author Harmeet Saini
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package quiz
+ */
+
+require_once("../../config.php");
+require_once($CFG->dirroot.'/mod/quiz/editlib.php');	//needed for tabs.php
+require_once("omruploadconfig_form.php");
+require_once($CFG->libdir . '/uploadlib.php');
+//require_once("locallib.php");
+//require_once($CFG->dirroot.'/lib/questionlib.php');
+
+$id   = optional_param('cmid', 0, PARAM_INT);     // course module id not quiz id
+$thispageurl="$CFG->wwwroot/mod/quiz/omruploadconfig.php?cmid=$id";
+
+if (! $cm = get_coursemodule_from_id('quiz', $id)) {
+	error("There is no coursemodule with id $id");
+}
+
+if (! $course = get_record("course", "id", $cm->course)) {
+	error("Course is misconfigured");
+}
+
+if (! $quiz = get_record("quiz", "id", $cm->instance)) {
+	error("The quiz with id $cm->instance corresponding to this coursemodule $id is missing");
+}
+
+if (! $omrquiz = get_record("omrquiz", "quizid", $cm->instance)) {
+	error("The specified omrquiz does not exist");
+}
+
+require_login($course->id, false, $cm);
+$navigation = build_navigation(get_string('upload_omr_configuration','quiz'), $cm);                          //edited by Jalpa
+print_header_simple(get_string('upload_omr_configuration','quiz'), '', $navigation, "", "", true, "");       //edited by Jalpa
+$currenttab = 'omr';
+$mode = 'omrconfig';
+include('tabs.php');
+
+//for deleting attempts and answer data when user selected reupload configuration where number of variants in this configuration differ from previous omr configuration
+if(optional_param('yes',NULL,PARAM_CLEAN)){
+	$response=optional_param('response',NULL, PARAM_RAW);
+	$response=stripslashes($response);
+	$response=unserialize($response);
+
+	set_omrconfig($quiz,$response,$omrquiz->id,$cm->id,$course->id, true , $thispageurl);
+
+	echo "<form name=\"continueform\" method=\"post\" action=\"omr.php?cmid=$id\">";
+	echo'<center><input type="submit" name="continue" value="continue" /></center>';
+	echo'</form>';
+
+	print_footer($course);
+	exit;
+}
+
+
+$displayform=true;
+$import_form = new omrconfig_import_form($thispageurl);
+
+if(! $form = $import_form->get_data() and !optional_param('yes',0,PARAM_CLEAN)) {
+	if(!optional_param('change',0,PARAM_CLEAN) and !optional_param('continue',0,PARAM_CLEAN)){
+		if($omrquizconfig=get_record('omrquiz', 'quizid',$quiz->id)){
+			if($omrquizconfig->bookletcount > 0){
+				$displayform=false;
+				print_box_start();
+				notify(get_string('configinfo', 'quiz'));
+				echo(get_string('noofvariants','quiz',$omrquizconfig->bookletcount));
+				echo(get_string('rollnoposition','quiz',$omrquizconfig->rollnoposition));
+				echo(get_string('variantposition','quiz',$omrquizconfig->bookletposition));
+				echo(get_string('answerstringposition','quiz',$omrquizconfig->ansposition));
+				echo(get_string('rollnolength','quiz',$omrquizconfig->rollnolength));
+				echo(get_string('variantnolength','quiz',$omrquizconfig->bookletlength));
+
+				
+				//for displaying change button after displaying already present data.
+				echo "<form name=\"changeform\" method=\"post\" action=\"$thispageurl&\">";
+				echo'<center><input type="submit" value="change" name="change" /></center>';
+				echo'</form>';
+				print_box_end();
+			}
+		}
+	}
+}
+
+if($displayform){
+	if ($import_form->is_cancelled()){
+		redirect($thispageurl);
+	}
+	if($form) {
+		// file checks out ok
+		$fileisgood = false;
+		if (! empty($form->choosefile)) {
+			$importfile = "{$CFG->dataroot}/{$COURSE->id}/{$form->choosefile}";
+			$realfilename = $form->choosefile;
+			if (file_exists($importfile)) {
+				$fileisgood = true;
+			}
+			else {
+				print_error('uploadproblem', 'moodle', $form->choosefile);
+			}
+		}
+		else {
+			$realfilename = $import_form->get_importfile_realname();
+			if (! $importfile = $import_form->get_importfile_name()) {
+				print_error('uploadproblem', 'moodle');
+			}
+			else {
+				$fileisgood = true;
+			}
+		}
+		if ($fileisgood){
+			if (configimportprocess($quiz,$importfile,$omrquiz->id,$cm->id, $course->id , $thispageurl)){
+				print_error('importerror', 'quiz', $thispageurl->out());
+			}
+		}
+		//for printing continue button after displaying config data.
+		echo "<form name=\"continueform\" method=\"post\" action=\"omr.php?cmid=$id\">";
+		echo'<center><input type="submit" name="continue" value="continue" /></center>';
+		echo'</form>';
+		//print_box_end();
+	}
+	else{
+		print_heading_with_help('Upload a Configuration File','omrconfigupload','quiz',NULL,false); //edited by Jalpa
+		$import_form->display();
+	}
+}
+print_footer($course);
+
+//-------------------------------------Functions---------------------------------------------
+
+/**
+ * Reads the uploaded configuration file and processes it.
+ * It calls {@link readomrdata()} for getting the file contents as an array.
+ * calls {@link set_omrquiz()} for setting up the configuration for OMR quiz
+ *
+ * @param Object $quiz
+ * @param String $importfile
+ * @param String $omrquizid
+ * @param String $cmid
+ * @param String $courseid
+ * @param String $thispageurl
+ */
+function configimportprocess($quiz,$importfile,$omrquizid,$cmid, $courseid, $thispageurl) {
+	if (! $lines = readomrdata($importfile)) {
+		notify( get_string('cannotread','quiz') );
+		return false;
+	}
+	if (! $response = trimresponse($lines)) {
+		notify( "some problem occured, no data present" );
+		return false;
+	}
+	set_omrconfig($quiz,$response,$omrquizid,$cmid,$courseid,false,$thispageurl);
+}
+
+/**
+ * reads the contents of a file in an array
+ * @param array $filename
+ * @return array $filearray the array with contents as the whole file, false on failure.
+ */
+function readomrdata($filename) {
+	if (is_readable($filename)) {
+		$filearray = file($filename);
+		/// Check for Macintosh OS line returns (ie file on one line), and fix
+		if (ereg("\r", $filearray[0]) AND !ereg("\n", $filearray[0])) {
+			return explode("\r", $filearray[0]);
+		}
+		else {
+			return $filearray;
+		}
+	}
+	return false;
+}
+
+/*
+ * Just trims every line in array
+ * @param array   $lines file contents as array
+ * @return array  $response trimmed response
+ */
+function trimresponse($lines) {
+	foreach($lines as $line) {
+		$line = trim($line);
+		$response[]=$line;
+	}
+	return $response;
+}
+
+/**
+ * Extracts OMR configuration parameters from uploaded file. Stores the information in database and then displays the
+ * configuration information on screen.
+ * Reuploads the OMR configuration if configuration already present
+ *
+ * @param Object  $quiz
+ * @param array   $response The array having the contents of uploaded configuration file
+ * @param String  $omrquizid
+ * @param String  $cmid
+ * @param String  $courseid
+ * @param boolean $deleteattempts whether to delete attempts on configuration reupload. False by default.
+ * @param String  $thispageurl
+ */
+function set_omrconfig($quiz,$response,$omrquizid,$cmid,$courseid,$deleteattempts=false, $thispageurl){
+
+	if($deleteattempts){
+		$omrquiz_config=new object();
+		foreach($response as $key => $value){
+			$omrquiz_config->$key=$value;
+		}
+	}else{
+		$omrquiz_config=new object();
+
+		// extract config params from uploaded file
+		$conf_param=array(1=>"bookletcount","rollnoposition","bookletposition","ansposition","rollnolength","bookletlength");
+		$a=1;
+
+		// search for every configuration parameter in the uploaded configuration file.
+		foreach($response as $value){
+			$pos=stripos($value,$conf_param[$a]);
+			if($pos!==false){
+				$pos1=stripos($value,':');
+				$parameter=substr($value,$pos1+1);
+				trim($parameter);
+				$temp=$conf_param[$a];
+				$$temp=$parameter;
+				$a=$a+1;
+			}
+		}
+		$omrquiz_config->id=$omrquizid;
+		$omrquiz_config->bookletcount=$bookletcount;
+		$omrquiz_config->rollnoposition=$rollnoposition;
+		$omrquiz_config->bookletposition=$bookletposition;
+		$omrquiz_config->ansposition=$ansposition;
+		$omrquiz_config->rollnolength=$rollnolength;
+		$omrquiz_config->bookletlength=$bookletlength;
+
+		//TODO  check for input validation
+	}
+
+
+	//print_box_start();
+	if($previousomrconfig = get_records('omrquiz', 'quizid', $quiz->id, $sort='id') ){
+		foreach($previousomrconfig as $key => $value){
+			$issetbookletcount= $value->bookletcount;
+			break;
+		}
+	}
+
+	if(!$issetbookletcount){	// because if bookletcount is set that means config is already uploaded
+		// insert information in mdl_omrquiz table
+		if(!update_record('omrquiz', $omrquiz_config)){
+			//it shud b an error statement..
+			error("could not update omrquiz table with omr config");
+		}
+
+		// now code for displaying some information after configuration upload to database...
+		print_box_start();
+		notify(get_string('configinfo', 'quiz'));
+		echo(get_string('noofvariants','quiz',$omrquiz_config->bookletcount));
+		echo(get_string('rollnoposition','quiz',$omrquiz_config->rollnoposition));
+		echo(get_string('variantposition','quiz',$omrquiz_config->bookletposition));
+		echo(get_string('answerstringposition','quiz',$omrquiz_config->ansposition));
+		echo(get_string('rollnolength','quiz',$omrquiz_config->rollnolength));
+		echo(get_string('variantnolength','quiz',$omrquiz_config->bookletlength));
+		print_box_end();
+	}else{
+		//reupload omr configuraion
+		//reuploading configuration when booklet count is not same as earlier
+		if(!($issetbookletcount == $omrquiz_config->bookletcount)){
+			// first notify user that attempts will be deleted and ask whether to continue or not
+			if(!$deleteattempts){
+				foreach($omrquiz_config as $key => $value){
+					$pass[$key]=$value;
+				}
+
+				$pass=serialize($pass);
+					
+				//$navigation = build_navigation("change configuration?", $cm);
+				//print_header_simple("change configuration?", '', $navigation, "", "", true, "");
+				print_simple_box_start('center', '60%', '#FFAAAA', 20, 'noticebox');
+				notify(get_string('deletewarning','quiz'));
+				print_heading(get_string('surechangeconfig','quiz'));
+				echo'<form name="reupload" method="post" action='.$thispageurl.'>';
+				echo'<input type="hidden" name="response" value='.$pass.' >';
+				echo'<input type="hidden" name="test" value="5" >';
+				echo'<input type="submit" name="yes" value="yes" >';
+				echo'<input type="button" value="no" onclick="javascript:history.go(-1);" >';
+				print_simple_box_end();
+				print_footer();
+				exit;
+
+			}else{
+				//delete user attempts and answer data for all the variants if there is a change in bookletcount
+
+				// first delete attempts related to all the variants for this omrquiz
+				$context = get_context_instance(CONTEXT_MODULE, $cmid);
+				require_capability('mod/quiz:deleteattempts', $context);
+				$attemptids= get_records('quiz_attempts', 'quiz', $quiz->id, 'id', 'id');
+				if($attemptids != ''){
+					foreach($attemptids as $attemptid) {
+						add_to_log($courseid, 'quiz', 'delete attempt', 'report.php?id=' . $cmid,
+						$attemptid, $cmid);
+						quiz_delete_attempt($attemptid, $quiz);
+					}
+				}
+					
+				// check if answers and variants exist already then only delete
+				if(record_exists('omrquiz_booklet', 'omrquizid', $omrquizid)){
+
+					//delete all the answer data associated with this omrquiz.
+					if(record_exists('omrquiz_answers', 'omrquizid', $omrquizid)){
+						delete_records('omrquiz_answers', 'omrquizid', $omrquizid);
+					}
+
+
+					// then delete all the variants
+					if(!delete_records('omrquiz_booklet', 'omrquizid', $omrquizid)){
+						echo"could not delete omrquiz booklets ";
+					}
+				}
+
+
+				// now update the record for new configuration
+				if(!update_record('omrquiz', $omrquiz_config)){
+					echo"could not update omrquiz table with omr config";
+				}
+				print_box_start();
+				notify(get_string('newconfiginfo_afterdelete', 'quiz'));
+				echo(get_string('noofvariants','quiz',$omrquiz_config->bookletcount));
+				echo(get_string('rollnoposition','quiz',$omrquiz_config->rollnoposition));
+				echo(get_string('variantposition','quiz',$omrquiz_config->bookletposition));
+				echo(get_string('answerstringposition','quiz',$omrquiz_config->ansposition));
+				echo(get_string('rollnolength','quiz',$omrquiz_config->rollnolength));
+				echo(get_string('variantnolength','quiz',$omrquiz_config->bookletlength));
+				print_box_end();
+			}
+
+				
+		}else{
+			//reuploading configuration when booklet count is same as earlier
+			if(!update_record('omrquiz', $omrquiz_config)){
+				error("could not update omrquiz table with omr configuration");
+			}
+			print_box_start();
+			notify(get_string('newconfiginfo', 'quiz'));
+			echo(get_string('noofvariants','quiz',$omrquiz_config->bookletcount));
+			echo(get_string('rollnoposition','quiz',$omrquiz_config->rollnoposition));
+			echo(get_string('variantposition','quiz',$omrquiz_config->bookletposition));
+			echo(get_string('answerstringposition','quiz',$omrquiz_config->ansposition));
+			echo(get_string('rollnolength','quiz',$omrquiz_config->rollnolength));
+			echo(get_string('variantnolength','quiz',$omrquiz_config->bookletlength));
+			print_box_end();
+		}
+	}
+}
+?>
Index: moodle/mod/quiz/omruploadconfig_form.php
--- moodle/mod/quiz/omruploadconfig_form.php No Base Revision
+++ moodle/mod/quiz/omruploadconfig_form.php Locally New
@@ -0,0 +1,51 @@
+<?php
+require_once($CFG->libdir.'/formslib.php');
+
+//class for creating upload form for OMR configuration upload. It is called from omruploadconfig.php
+class omrconfig_import_form extends moodleform {
+
+    function definition() {
+        global $COURSE;
+        $mform    =& $this->_form;
+       // $contexts   = $this->_customdata['contexts'];
+        
+//--------------------------------------------------------------------------------
+        $mform->addElement('header', 'importfileupload', get_string('importfileupload','quiz'));
+
+        $this->set_upload_manager(new upload_manager('newfile', true, false, $COURSE, false, 0, false, true, false));
+        $mform->addElement('file', 'newfile', get_string('upload'));
+//--------------------------------------------------------------------------------
+        $mform->addElement('submit', 'submitbutton', get_string('uploadthisfile'));
+
+//--------------------------------------------------------------------------------
+        if (has_capability('moodle/course:managefiles', get_context_instance(CONTEXT_COURSE, $COURSE->id))){
+            $mform->addElement('header', 'importfilearea', get_string('importfilearea','quiz'));
+
+            $mform->addElement('choosecoursefile', 'choosefile', get_string('choosefile','quiz'));
+//--------------------------------------------------------------------------------
+            $mform->addElement('submit', 'submitbutton', get_string('importfromthisfile','quiz'));
+        }
+//--------------------------------------------------------------------------------
+        $mform->addElement('static', 'dummy', '');
+        $mform->closeHeaderBefore('dummy');
+    }
+    
+    
+function get_importfile_name(){
+        if ($this->is_submitted() and $this->is_validated()) {
+            // return the temporary filename to process
+            return $this->_upload_manager->files['newfile']['tmp_name'];
+        }else{
+            return  NULL;
+        }
+    }
+function get_importfile_realname(){
+        if ($this->is_submitted() and $this->is_validated()) {
+            // return the temporary filename to process
+            return $this->_upload_manager->files['newfile']['name'];
+        }else{
+            return  NULL;
+        }
+    }
+}
+?>
\ No newline at end of file
Index: moodle/mod/quiz/tabs.php
--- moodle/mod/quiz/tabs.php Base (1.21.2.4)
+++ moodle/mod/quiz/tabs.php Locally Modified (Based On 1.21.2.4)
@@ -41,6 +41,14 @@
     $row[] = new tabobject('edit', "$CFG->wwwroot/mod/quiz/edit.php?cmid=$cm->id", get_string('edit'));
 }
 
+//---------------------------------------------------For OMR Quiz,------------------------------------------------
+if(record_exists('omrquiz', 'quizid', $quiz->id)){
+	if (has_capability('mod/quiz:manage', $context)) {
+		$row[] = new tabobject('omr', "$CFG->wwwroot/mod/quiz/omr.php?cmid=$cm->id", get_string('omr_tab','quiz'));
+	}
+}
+//----------------------------------------------author@ Harmeet Saini---------------------------------------------
+
 if ($currenttab == 'info' && count($row) == 1) {
     // Don't show only an info tab (e.g. to students).
 } else {
@@ -96,8 +104,24 @@
 
 }
 
+//---------------------------------------------------For OMR Quiz,------------------------------------------------
+if ($currenttab == 'omr' and isset($mode)) {
+	$activated[]= 'omr';
+	$row=array();
+	$currenttab=$mode;
+	if (has_capability('mod/quiz:manage', $context)) {
+		$row[] = new tabobject('omrconfig', "$CFG->wwwroot/mod/quiz/omruploadconfig.php?cmid=$cm->id",get_string('omr_configuration_tab','quiz'));
+		$row[] = new tabobject('booklets', "$CFG->wwwroot/mod/quiz/omr.php?cmid=$cm->id",get_string('omr_variant_tab','quiz'));
+		$row[] = new tabobject('attendence', "$CFG->wwwroot/mod/quiz/omrattendence.php?cmid=$cm->id",get_string('omr_attendance_tab','quiz'));
+		$row[] = new tabobject('answers', "$CFG->wwwroot/mod/quiz/omranswers.php?cmid=$cm->id",get_string('omr_answers_tab','quiz'));
+		$row[] = new tabobject('process', "$CFG->wwwroot/mod/quiz/omrevaluate.php?cmid=$cm->id",get_string('omr_attempts_tab','quiz'));
+	}
+	$tabs[]=$row;
+}
+//----------------------------------------------author@ Harmeet Saini---------------------------------------------
+
 if (!$quiz->questions) {
-    $inactive += array('info', 'reports', 'preview');
+    $inactive += array('info', 'reports', 'preview', 'omr');		//edited For OMR Quiz (added 'omr' in $inactive)
 }
 
 print_tabs($tabs, $currenttab, $inactive, $activated);
Index: moodle/mod/quiz/version.php
--- moodle/mod/quiz/version.php Base (1.128.2.4)
+++ moodle/mod/quiz/version.php Locally Modified (Based On 1.128.2.4)
@@ -5,7 +5,7 @@
 //  This fragment is called by moodle_needs_upgrading() and /admin/index.php
 ////////////////////////////////////////////////////////////////////////////////
 
-$module->version  = 2007101511;   // The (date) version of this module
+$module->version  = 2007101611;   // The (date) version of this module
 $module->requires = 2007101509;   // Requires this Moodle version
 $module->cron     = 0;            // How often should cron check this module (seconds)?
 
