﻿//<using>
//  nui/nui.js
//  nui/prototype.js
//  nui/ajax.js
//  nui/util.js
//  nui/widget.js
//  nui/widget/popup.js
//  nui/quill/entity/*
//  nui/quill/processor/*
//</using>

/**
 * The survey proxy used in netranking.cn 
 * Copyright 2007, NetRanking.cn
 *
 * @class NUI.Quill.Proxy 
 */
NUI.Quill.Proxy = (function() {
    var g_ajax = NUI.Ajax,
        g_enum = NUI.Quill.Enum,
        g_entity = NUI.Quill.Entity,
        g_prcs = NUI.Quill.Processor,
        g_ns = NUI.Quill.Proxy,
        g_ht = NUI.Util.DataStructure.HashTable;
    
    return {
        Survey : (function() {
            var m_parsers = {
                toServer : function(vSurvey) {
                    if(vSurvey == null) {
                        return null;
                    }
                    var retval = NUI.Util.ObjectService.clone(vSurvey);
                    NUI.Util.ObjectService.remove(retval, "questionSet");
                    NUI.Util.ObjectService.remove(retval, "pageTags");
                    retval.pageTags = vSurvey.pageTags.keys();
                    NUI.Util.ObjectService.remove(retval, "portionTags"); 
                    retval.portionTags = vSurvey.portionTags.elements("qstId", "value");
                    NUI.Util.ObjectService.remove(retval, "jumper");
                    var elems = vSurvey.jumper.elements("qstId", "jpOpts"),
                        count = elems.length;
                    for(var i=0; i<count; i++) {
                        var qJp = elems[i]["jpOpts"].elements("optIdx", "targetQIds"),
                            qcount = qJp.length;
                        for(var k=0; k<qcount; k++) {
                            qJp[k]["targetQIds"] = qJp[k]["targetQIds"].keys();
                        }
                        elems[i]["jpOpts"] = qJp;
                    }
                    retval.jumper = elems;
                    NUI.Util.ObjectService.remove(retval, "branch");
                    var elems = vSurvey.branch.elements("qstId", "brOpts"),
                        count = elems.length;
                    for(var i=0; i<count; i++) {
                        elems[i]["brOpts"] = elems[i]["brOpts"].elements("optIdx", "value");
                    }
                    retval.branch = elems;
                    return retval;
                },
                fromServer : function(vSId, vSurvey) {
                    if(vSurvey == null) {
                        return null;
                    }
                    var retval = new g_entity.Survey();
                    retval.id = vSId;
                    retval.caption = vSurvey.caption;
                    retval.subcaption = vSurvey.subcaption;
                    retval.description = vSurvey.description;
                    retval.header = vSurvey.header;
                    retval.footer = vSurvey.footer;
                    retval.questionSet = new g_ht();
                    retval.qIdList = vSurvey.qIdList;
                    retval.pageTags = new g_ht();
                    var pgtags = vSurvey.pageTags,
                        pgCount = pgtags.length;
                    for(var i=0; i<pgCount; i++) {
                        retval.pageTags.setValue(pgtags[i], true);
                    }
                    retval.portionTags = new g_ht();
                    retval.portionTags.setValues(vSurvey.portionTags, "qstId", "value");
                    retval.jumper = new g_ht();
                    retval.jumper.setValues(vSurvey.jumper, "qstId", "jpOpts");
                    retval.jumper.walkTable(function(vQId, vQValue) {
                        var qJp = new g_ht();
                        qJp.setValues(vQValue, "optIdx", "targetQIds");
                        qJp.walkTable(function(vOptIdx, vTgtQIds) {
                            var optValue = new g_ht(),
                                count = vTgtQIds.length;
                            for(var i=0; i<count; i++) {
                                optValue.setValue(vTgtQIds[i], true);
                            }
                            qJp.setValue(vOptIdx, optValue);
                        });
                        retval.jumper.setValue(vQId, qJp);
                    });
                    retval.branch = new g_ht();
                    retval.branch.setValues(vSurvey.branch, "qstId", "brOpts");
                    retval.branch.walkTable(function(vQId, vQValue) {
                        var qBr = new g_ht();
                        qBr.setValues(vQValue, "optIdx", "value");
                        retval.branch.setValue(vQId, qBr);
                    });
                    return retval;
                }
            };
            return {
                /** 
                 * Create a survey
                 * @param vSurvey {int}. The survey to be created
                 * @param vFunc(vSurveyId) {funciton}. The function to execute after survey is created
                 */
                createSurvey : function(vSurvey, vFunc) {
                    var surveyToBeCreated = m_parsers.toServer(vSurvey);
                    if(surveyToBeCreated == null) {
                        vFunc(-1);
                        return;
                    }
                    g_ajax.call("CreateSurvey", {
                        args : [surveyToBeCreated],
                        func : {
                            success : function(vSurveyId) {
                                vFunc(vSurveyId);
                            }
                        }
                    });
                },
                
                /** 
                 * Get a survey
                 * @param vSurveyId {int}. The survey's id
                 * @param vFunc(vSurvey) {funciton}. The function to execute after survey is got
                 */
                getSurvey : function(vSurveyId, vFunc) {
                    if(vSurveyId == null || vSurveyId <= 0) {
                        vFunc(null);
                        return;
                    }
                    g_ajax.call("GetSurvey", {
                        args : [vSurveyId],
                        func : {
                            success : function(vSurvey) {
                                if(vSurvey != null) {
                                    vFunc(m_parsers.fromServer(vSurveyId, vSurvey));
                                } else {
                                    vFunc(null);
                                }
                            }
                        }
                    });
                },
                
                /** 
                 * Delete a survey
                 * @param vSurveyId {int}. The survey's id
                 * @param vFunc(boolean) {funciton}. The function to execute after survey is got
                 */
                deleteSurvey : function(vSurveyId, vFunc) {
                },
                
                /**
                 * Save a survey
                 * @param vSurvey {object}. The survey to be saved
                 * @param vFunc(vSurveyId) {funciton}. The function to execute after survey saved
                 */
                saveSurvey : function(vSurvey, vFunc) {
                    var surveyToBeSaved = m_parsers.toServer(vSurvey);
                    if(surveyToBeSaved == null) {
                        vFunc(-1);
                        return;
                    }
                    g_ajax.call("SaveSurvey", {
                        args : [surveyToBeSaved],
                        func : {
                            success : function(vSurveyId) {
                                vFunc(vSurveyId);
                            }
                        }
                    });
                },

                /**
                 * Save a survey as another survey
                 * @param vSurveyId {int}. The id of the survey to be saved
                 * @param vNewCaption {string}. The new survey's caption
                 * @param vFunc(vNewSurveyId) {function}.
                 */
                saveAsSurvey : function(vSurveyId, vNewCaption, vFunc) {
                    g_ajax.call("SurveySaveAs", {
                        args : [vSurveyId, vNewCaption],
                        func : {
                            success : function(vNewSurveyId) {
                                vFunc(vNewSurveyId);
                            }
                        }
                    });
                }
            };
        })(),
        
        Question : (function() {
            /**
             * Get the question parser
             */
            function _getParser(vQuestionType) {
                if(vQuestionType == null) {
                    return null;
                }
                var typeValue = null;
                NUI.Util.ObjectService.searchObject(g_enum.QuestionType, function(vName) {
                    var type = g_enum.QuestionType[vName];
                    if(type.id == vQuestionType) {
                        typeValue = type.value;
                        return true;
                    }
                    return false;
                });
                if(typeValue == null) {
                    return null;
                }
                var parser = {
                    toServer : function(vQuestion) {
                        if(vQuestion == null) {
                            return null;
                        }
                        var retval = NUI.Util.ObjectService.clone(vQuestion);
                        NUI.Util.ObjectService.remove(retval, "modified");
                        return retval;
                    },
                    fromServer : function(vQId, vQuestion) {
                        if(vQuestion == null) {
                            return null;
                        }
                        var retval = new g_entity.Question[typeValue]();
                        NUI.Util.ObjectService.annex(retval, vQuestion);
                        retval.id = vQId;
                        retval.modified = false;
                        return retval;
                    }
                };
                return parser;
            }
            
            return {
                getParser : _getParser,
                /**
                 * Get question entity from the server
                 * @param vSurveyId {int}. The id of the question's owner survey
                 * @param vQuestionId {int} The id of the question to be got
                 * @param vFunc(vQuestion) {function} The function to execute after getting the entity
                 */
                getQuestion : function(vSurveyId, vQuestionId, vFunc) {
                    if(vQuestionId == null || vQuestionId <= 0) {
                        vFunc(null);
                        return;
                    }
                    g_ajax.call("GetQuestion", {
                        args : [vSurveyId, vQuestionId],
                        func : {
                            success : function(vQuestion) {
                                var returnedQuestion = null;
                                if(vQuestion != null) {
                                    var parser = _getParser(vQuestion.type);
                                    if(parser != null) {
                                        returnedQuestion = parser.fromServer(vQuestionId, vQuestion);
                                    }
                                }
                                vFunc(returnedQuestion);
                            }
                        }
                    });
                },
                
                /**
                 * Get a special question entity from the server
                 * @param vType {int}. The type of the special question
                 * @param vFunc(vQuestion) {function} The function to execute after getting the entity
                 */
                getSpecialQuestion : function(vType, vFunc) {
                    if(vType == null) {
                        vFunc(null);
                        return;
                    }
                    g_ajax.call("GetSpecialQuestion", {
                        args : [vType],
                        func : {
                            success : function(vQuestion) {
                                var returnedQuestion = null;
                                if(vQuestion != null) {
                                    var parser = _getParser(vQuestion.type);
                                    if(parser != null) {
                                        returnedQuestion = parser.fromServer(-vType, vQuestion);
                                    }
                                }
                                vFunc(returnedQuestion);
                            }
                        }
                    });
                },
                
                /**
                 * Get question entity from the server
                 * @param vSurveyId {int}. The id of the question's owner survey
                 * @param vQuestionId {int} The id of the question to be got
                 * @param vFunc(vQuestion) {function} The function to execute after getting the entity
                 */
                getQuestionAnswerSet : function(vSurveyId, vQuestionId, vVolunteer, vFunc) {
                    if(vQuestionId == null || vQuestionId <= 0 || vVolunteer == null) {
                        vFunc(null);
                        return;
                    }
                    g_ajax.call("GetQuestionAnswerSet", {
                        args : [vSurveyId, vQuestionId, vVolunteer],
                        func : {
                            success : function(vQuestionAnswerSet) {
                                var Qsts = null;
                                if(vQuestionAnswerSet != null) {
                                    var parser = _getParser(vQuestionAnswerSet.question.type),
                                    Qsts = {
                                        question : parser.fromServer(vQuestionAnswerSet.id, 
                                            vQuestionAnswerSet.question),
                                        answer : vQuestionAnswerSet.answer
                                    };
                                }
                                vFunc(Qsts);
                            }
                        }
                    });
                },
                
                /**
                 * Get the next page's questions and from the server
                 * @param vSurveyId {int}.
                 * @param vFunc(vQuestionAnswerSets) {function} The function to execute after getting the questions
                 *  vQuestionAnswerSet = {
                 *      question : question body
                 *      answer : answer body
                 *  }
                 */
                getOnePage : function(vSurveyId, vFunc) {
                    if(vSurveyId == null || vSurveyId <= 0) {
                        vFunc([]);
                        return;
                    }
                    g_ajax.call("GetOnePage", {
                        args : [vSurveyId],
                        func : {
                            success : function(vQuestionAnswerSets) {
                                if(vQuestionAnswerSets == null) {   // is filter out
                                    vFunc(null);
                                    return;
                                }
                                var Qsts = [];
                                var count = vQuestionAnswerSets.length;
                                for(var i=0; i<count; i++) {
                                    var qaset = vQuestionAnswerSets[i];
                                    if(qaset == null || qaset.question == null) {
                                        continue;
                                    }
                                    var parser = _getParser(qaset.question.type),
                                        item = {
                                            question : parser.fromServer(qaset.id, qaset.question),
                                            answer : qaset.answer
                                        };
                                    Qsts[Qsts.length] = item;
                                }
                                vFunc(Qsts);
                            }
                        }
                    });
                },
                
                /**
                 * Get the one page's questions and answers and from the server
                 * @param vSurveyId {int}.
                 * @param vPageIndex {int}.
                 * @param vFunc(vQuestionAnswerSets) {function} The function to execute after getting the questions
                 *  vQuestionAnswerSet = {
                 *      question : question body
                 *      answer : answer body
                 *  }
                 */
                getOnePageByIndex : function(vSurveyId, vPageIndex, vFunc) {
                    if(vSurveyId == null || vSurveyId <= 0 || vPageIndex  == null || vPageIndex < 0) {
                        vFunc([]);
                        return;
                    }
                    g_ajax.call("GetOnePageByIndex", {
                        args : [vSurveyId, vPageIndex],
                        func : {
                            success : function(vQuestionAnswerSets) {
                                if(vQuestionAnswerSets == null) {   // is filter out
                                    vFunc(null);
                                    return;
                                }
                                var Qsts = [];
                                var count = vQuestionAnswerSets.length;
                                for(var i=0; i<count; i++) {
                                    var qaset = vQuestionAnswerSets[i];
                                    if(qaset == null || qaset.question == null) {
                                        continue;
                                    }
                                    var parser = _getParser(qaset.question.type),
                                        item = {
                                            question : parser.fromServer(qaset.id, qaset.question),
                                            answer : qaset.answer
                                        };
                                    Qsts[Qsts.length] = item;
                                }
                                vFunc(Qsts);
                            }
                        }
                    });
                },
                
                /**
                 * Save a question entity
                 * @param vSurveyId {int}. The id of the question's owner survey
                 * @param vQuestion {object} The question entity
                 * @param vFunc(vIsSuccess) {function} The function to execute after saving the entity
                 */
                saveQuestion : function(vSurveyId, vQuestion, vFunc) {
                    if(vQuestion == null) {
                        vFunc(false);
                        return;
                    }
                    var parser = _getParser(vQuestion.type);
                    if(parser == null) {
                        vFunc(false);
                        return;
                    }
                    var qstToSave = parser.toServer(vQuestion);
                    if(qstToSave == null) {
                        vFunc(false);
                        return;
                    }
                    g_ajax.call("SaveQuestion", {
                        args : [vSurveyId, qstToSave],
                        func : {
                            success : function(vIsSuccess) {
                                if(!vIsSuccess) {
                                    NUI.Widget.Alert("保存题目出错，请稍后再试");
                                }
                                vFunc(vIsSuccess);
                            }
                        }
                    });
                }
            };
        })(),
        
        Answer : (function() {
            return {
                /**
                 * Save a answer
                 * @param vSurveyId {int}
                 * @param vQid {int}. The question's id
                 * @param vAnswer {object}. The answer to be saved
                 * @param vFunc(vIsSuccess) {boolean}. The function to execute after answer is saved
                 */
                saveAnswer : function(vSurveyId, vQuestionId, vAnswer, vFunc) {
                    var m_fun = vFunc ? vFunc : function() {};
                    if(vSurveyId <= null || vQuestionId <= 0 || vAnswer == null) {
                        vFunc(false);
                        return;
                    }
                    g_ajax.call("SaveAnswer", {
                        args : [vSurveyId, vQuestionId, vAnswer],
                        func : {
                            success : function(vIsSuccess) {
                                m_fun(vIsSuccess);
                            }
                        }
                    });
                }
            };
        })()
    };
})();
