00001
00002
00003
00004
00005 #ifndef _QUESTION_H_
00006 #define _QUESTION_H_
00007
00008 #include <config.h>
00009
00010 #include <iostream>
00011 #include <string>
00012 #include <vector>
00013
00014 #include <libxml/parser.h>
00015 #include <libxml/xmlwriter.h>
00016 #include "lua/lua.hpp"
00017
00018 #include "utils.h"
00019
00020 namespace Limiro
00021 {
00022
00024 class Result
00025 {
00026 public:
00028 Result(bool c, std::string ans="") {correct=c; correctAnswer=ans;};
00030 operator bool() {return correct;};
00031
00033 bool correct;
00034
00036 std::string correctAnswer;
00037 };
00038
00040 class DynamicString
00041 {
00042 public:
00043 DynamicString();
00044 DynamicString(const std::string& source, bool parse=true);
00045
00046 std::string bake(lua_State *L);
00047 bool isDynamic() const;
00048
00049 #ifdef DEBUG
00050 void print();
00051 #endif
00052
00053 private:
00055 class DPart
00056 {
00057 public:
00058 enum PartType
00059 {
00060 TypeString,
00061 TypeScript,
00062 TypeExpression
00063 };
00064
00065 DPart(const DPart& other);
00066 DPart(PartType type, const std::string& data);
00067 DPart operator+(const DPart& other);
00068
00069 std::string toString(lua_State *L);
00070 PartType type() const {return m_type;};
00071
00072 #ifdef DEBUG
00073 void print() const;
00074 #endif
00075
00076 private:
00077 PartType m_type;
00078 std::string m_data;
00079 };
00080 void parse(const std::string& source);
00081 std::vector<DPart> m_parts;
00082
00083 };
00084
00085
00087 class Question
00088 {
00089 public:
00091 enum Type
00092 {
00093 TypeUndefined = 0,
00094 TypeSimple,
00095 TypeMultipleChoice,
00096 TypeFloat,
00097 TypeYear,
00098 TypeDate,
00099 };
00101 Type getType() const {return m_type;};
00102
00104 operator bool() const {return m_type != TypeUndefined;};
00106 bool isSimple() const {return m_type == TypeSimple;};
00108 bool isMultipleChoice() const {return m_type == TypeMultipleChoice;};
00110 bool isFloat() const {return m_type == TypeFloat;};
00112 bool isYear() const {return m_type == TypeYear;};
00114 bool isDate() const {return m_type == TypeDate;};
00115
00117 virtual const std::string qText() const {return "";};
00119 virtual const std::string aText() const {return "";};
00121 virtual const std::vector<std::string> aList() const {return std::vector<std::string>();};
00122
00124 virtual const Result checkAnswer(const std::string& answer) const = 0;
00125
00127 virtual void writeXml(xmlTextWriterPtr writer) const = 0;
00128
00129 virtual ~Question(){};
00130
00131 protected:
00132 Type m_type;
00133 };
00134
00135
00137 class QuestionPattern
00138 {
00139 public:
00140 static QuestionPattern *fromXml(xmlNodePtr qNode);
00141
00143
00147 bool exhausted() const {return (m_num < 1);};
00148
00150 virtual bool isDynamic() const = 0;
00151
00153
00157 virtual Question *bake() = 0;
00158
00159 virtual ~QuestionPattern(){};
00160
00161 protected:
00162 static QuestionPattern *newQuestion(std::string type);
00163 void commonBuild(xmlNodePtr qNode);
00164
00167 virtual bool build(xmlNodePtr qNode) = 0;
00168
00169 std::string m_code;
00170 int m_num;
00171 };
00172
00173
00175
00178 class SimpleQuestion : public Question
00179 {
00180 friend class SimpleQuestionPattern;
00181
00182 public:
00183 SimpleQuestion() {m_type = TypeSimple;};
00184 virtual const std::string qText() const {return m_qText;};
00185 virtual const std::string aText() const {return m_aText;};
00186
00187 virtual const Result checkAnswer(const std::string& answer) const;
00188
00189 virtual void writeXml(xmlTextWriterPtr writer) const;
00190
00191 protected:
00192 std::string m_qText;
00193 std::string m_aText;
00194 };
00195
00197 class SimpleQuestionPattern : public QuestionPattern
00198 {
00199 public:
00200 virtual bool isDynamic() const;
00201 virtual Question *bake();
00202
00203 SimpleQuestionPattern() {};
00204 virtual ~SimpleQuestionPattern(){};
00205
00206 protected:
00207 virtual bool build(xmlNodePtr qNode);
00208
00209 DynamicString m_qText;
00210 DynamicString m_aText;
00211 };
00212
00214 class MultipleChoiceQuestion : public Question
00215 {
00216 friend class MultipleChoiceQuestionPattern;
00217
00218 public:
00219 MultipleChoiceQuestion() {m_type = TypeMultipleChoice;};
00220 virtual const std::string qText() const {return m_qText;};
00221 virtual const std::string aText() const {return m_aList[m_answer];};
00222 virtual const std::vector<std::string> aList() const {return m_aList;};
00223
00224 virtual const Result checkAnswer(const std::string& answer) const;
00225
00226 virtual void writeXml(xmlTextWriterPtr writer) const;
00227
00228 protected:
00229 std::string m_qText;
00230 std::vector<std::string> m_aList;
00231 int m_answer;
00232 };
00233
00235 class MultipleChoiceQuestionPattern : public QuestionPattern
00236 {
00237 public:
00238 virtual bool isDynamic() const;
00239 virtual Question *bake();
00240
00241 MultipleChoiceQuestionPattern() {};
00242 virtual ~MultipleChoiceQuestionPattern(){};
00243
00244 protected:
00245 virtual bool build(xmlNodePtr qNode);
00246
00247 DynamicString m_qText;
00248 std::vector<DynamicString> m_aList;
00249 int m_answer;
00250 };
00251
00253
00256 class YearQuestion : public SimpleQuestion
00257 {
00258 friend class YearQuestionPattern;
00259
00260 public:
00261 YearQuestion() {m_type = TypeYear;};
00262
00263 virtual const std::string aText() const {return utils::toString(m_aYear);};
00264
00265 virtual const Result checkAnswer(const std::string& answer) const;
00266
00267 virtual void writeXml(xmlTextWriterPtr writer) const;
00268
00269 protected:
00270
00271 int m_aYear;
00272 };
00273
00275 class YearQuestionPattern : public SimpleQuestionPattern
00276 {
00277 public:
00278 virtual Question *bake();
00279
00280 YearQuestionPattern() {};
00281 virtual ~YearQuestionPattern(){};
00282 };
00283
00285
00288 class FloatQuestion : public Question
00289 {
00290 friend class FloatQuestionPattern;
00291
00292 public:
00293 FloatQuestion() {m_type = TypeFloat;};
00294 virtual const std::string qText() const {return m_qText;};
00295 virtual const std::string aText() const {return (m_aMag + "," + m_aFrac);};
00296
00297 virtual const Result checkAnswer(const std::string& answer) const;
00298
00299 virtual void writeXml(xmlTextWriterPtr writer) const;
00300
00301 protected:
00302 std::string m_qText;
00303 std::string m_aMag;
00304 std::string m_aFrac;
00305 };
00306
00308 class FloatQuestionPattern : public QuestionPattern
00309 {
00310 public:
00311 virtual bool isDynamic() const;
00312 virtual Question *bake();
00313
00314 FloatQuestionPattern() {};
00315 virtual ~FloatQuestionPattern(){};
00316
00317 protected:
00318 virtual bool build(xmlNodePtr qNode);
00319
00320 DynamicString m_qText;
00321 DynamicString m_aText;
00322 };
00323
00325
00328 class DateQuestion : public SimpleQuestion
00329 {
00330 friend class DateQuestionPattern;
00331
00332 public:
00333 DateQuestion() {m_type = TypeDate;};
00334 virtual const std::string aText() const {return m_aTextUser;};
00335
00336 virtual const Result checkAnswer(const std::string& answer) const;
00337
00338 protected:
00339 std::string m_aTextUser;
00340 std::string m_aText;
00341 };
00342
00344 class DateQuestionPattern : public SimpleQuestionPattern
00345 {
00346 public:
00347 virtual bool isDynamic() const;
00348 virtual Question *bake();
00349
00350 DateQuestionPattern() {};
00351 virtual ~DateQuestionPattern(){};
00352
00353 protected:
00354 virtual bool build(xmlNodePtr qNode);
00355
00356 DynamicString m_qText;
00357 std::string m_aText;
00358 };
00359
00360 }
00361
00362 #endif // _QUESTION_H_