function MarkControl(option) {
    this.option = option;
    this.container = option.container;
    this.context = {
        imageServer: option.imageServer,
        staticServer: option.staticServer
    };
    //初始化容器结构
    this.initContainer();
    //初始化事件监听
    this.initTriggers(option);
    //初始化功能模块
    this.initModules(option);
    //初始化成功回调方法
    //console.log('MarkControl init success!');
    if (option.success != undefined && typeof(option.success) == 'function') {
        option.success();
    }
}

MarkControl.prototype.initContainer = function() {
    if (this.option.height != undefined) {
        this.container.height(this.option.height);
    } else {
        this.container.height($(window).height());
    }

    this.container.history = getDom(this.history_dom, this).appendTo(this.container).addClass('hide');
    this.container.center = getDom(this.center_dom, this).appendTo(this.container);
    this.container.sidebar = getDom(this.sidebar_dom, this).appendTo(this.container);

    this.container.center.header = getDom(this.center_header_dom, this).appendTo(this.container.center);
    this.initSidebar();
}

MarkControl.prototype.initSidebar = function() {
    this.container.sidebar.header = getDom(this.sidebar_header_dom, this).appendTo(this.container.sidebar);
    this.container.sidebar.tips = getDom(this.sidebar_tips_dom, this).appendTo(this.container.sidebar).find('p');
    this.container.sidebar.assistant = getDom(this.assistant_dom, this).appendTo(this.container);
    this.container.sidebar.assistantButton = getDom(this.assistant_button_dom, this).appendTo(this.container.sidebar.tips);
    this.container.sidebar.assistantButton.click(this, function(event) {
        var sidebar = event.data.container.sidebar;
        sidebar.assistant.toggle();
    });
    this.container.sidebar.header.find('#mark-user-name').html(this.option.userName);
}

MarkControl.prototype.initMarkFunction = function() {
    var functionList = this.container.sidebar.assistant.functionList;
    if (functionList == undefined) {
        functionList = getDom(this.mark_function_dom, this).appendTo(this.container.sidebar.assistant).find('#function-list');
        this.container.sidebar.assistant.functionList = functionList;
    }
}

//增加某个事件的监听方法
MarkControl.prototype.on = function(eventName, caller, callback, async) {
    if (eventName && callback && eventName.length > 0 && typeof(callback) == 'function') {
        if (async) {
            this.container.bind(eventName, callback);
        } else {
            if (this.triggers[eventName] == undefined) {
                this.triggers[eventName] = new Array();
            }
            this.triggers[eventName].push({
                caller: caller,
                callback: callback
            });
        }
    }
}

//触发某个事件，并传递事件相关内容
MarkControl.prototype.trigger = function(eventName, eventObject) {
    var result = true;
    if (eventName && eventName.length > 0) {
        var array = this.triggers[eventName];
        if (array != undefined && array.length > 0) {
            var event = {
                name: eventName
            }
            for (var i in array) {
                result = result & array[i].callback.call(array[i].caller, event, this.context, eventObject);
            }
        }
        this.container.trigger(eventName, this.context, eventObject);
    }
    return result;
}

//初始化事件监听
MarkControl.prototype.initTriggers = function(option) {
    if (this.triggers == undefined) {
        this.triggers = {};
    }
    if (option != undefined && option.on != undefined) {
        for (var name in option.on) {
            this.on(name, option.on[name]);
        }
    }

    this.on('mark.history.open', this, function(event, context, eventObject) {
        this.container.sidebar.assistant.hide();
        this.container.center.removeClass('span10');
        this.container.center.addClass('span8');
    });
    this.on('mark.history.close', this, function(event, context, eventObject) {
        this.container.sidebar.assistant.hide();
        this.container.center.removeClass('span8');
        this.container.center.addClass('span10');
    });
    this.on('task.get.before', this, function(event, context, eventObject) {
        this.container.sidebar.assistant.hide();
    });

    var self = this;
    $(document).keypress(this, function(event) {
        return event.data.trigger('key.press', event);
    });
    $(document).keydown(this, function(event) {
        return event.data.trigger('key.down', event);
    });
    $(document).keyup(this, function(event) {
        return event.data.trigger('key.up', event);
    });
    if (self.option.clearUrl) {
        $(window).unload(function() {
            $.post(self.option.clearUrl);
        });
    }
}

//初始化功能模块
MarkControl.prototype.initModules = function(option) {
    if (this.modules == undefined) {
        this.modules = {};
    }
    for (var name in this.defaultModules) {
        this.initModule(name, this.defaultModules[name]);
    }
    if (option.modules != undefined) {
        for (var name in option.modules) {
            this.initModule(name, option.modules[name]);
        }
    }
}

//指定初始化某个名称的模块
MarkControl.prototype.initModule = function(name, option) {
    var moduleInit = this.moduleConfig[name];
    if (this.modules[name] == undefined && moduleInit != undefined) {
        if (typeof(option) != 'object') {
            option = {};
        }
        option.markControl = this;
        this.modules[name] = new moduleInit(option);
    }
}

MarkControl.prototype.start = function(taskOption) {
    taskOption.markControl = this;
    var markControl = this;
    taskOption.success = function() {
        //console.log('TaskControl init success!');
        markControl.getTask();
    };
    taskOption.error = function(message) {
        //console.log(message);
    };
    this.taskControl = new TaskControl(taskOption);
    this.taskControl.init();
}

MarkControl.prototype.getTask = function() {
    var taskControl = this.taskControl;
    var markControl = this;
    var context = this.context;
    if (context.task != undefined) {
        return;
    }
    markControl.trigger('task.get.before');
    if (context.waitTask != undefined) {
        context.task = context.waitTask;
        context.waitTask = undefined;
        markControl.trigger('task.get.success');
    } else if (!taskControl.isFinish()) {
        taskControl.fetch(function(task) {
            context.task = task;
            markControl.trigger('task.get.success');
        }, function(status) {
            context.task = undefined;
            markControl.trigger('task.get.none', status);
        }, function() {
            context.task = undefined;
            markControl.trigger('task.get.error');
        });
    } else {
        markControl.trigger('task.get.finish');
    }
}

MarkControl.prototype.getHistory = function(data) {
    this.taskControl.history(data, function(result) {
        data.result = result;
        this.option.markControl.trigger('history.get.success', data);
    }, function(message) {
        data.message = message;
        this.option.markControl.trigger('history.get.error', data);
    });
}

MarkControl.prototype.setTask = function(task) {
    if (task != undefined) {
        this.trigger('task.get.before');
        if (this.context.task != undefined && this.context.waitTask == undefined) {
            this.context.waitTask = this.context.task;
        }
        this.context.task = task;
        this.trigger('task.get.success');
    }
}

MarkControl.prototype.submitTask = function() {
    var task = this.context.task;
    if (task != undefined) {
        task.markStepList = undefined;
        task.pictureUrls = undefined;
        task.answerUrls = undefined;

        this.trigger('task.submit.before');
        this.taskControl.submit(task, function() {
            this.option.markControl.context.task = undefined;
            this.option.markControl.trigger('task.submit.success');
            this.option.markControl.getTask();
        }, function(message) {
            this.option.markControl.trigger('task.submit.error', message);
        });
    }
}

//其他通用方法
String.prototype.startWith = function(prefix) {
    return this.indexOf(prefix) === 0;
}
String.prototype.endWith = function(suffix) {
    return this.match(suffix + "$") == suffix;
};

//日期格式化
Date.prototype.format = function(fmt) { //author: meizz 
    var o = {
        "M+": this.getMonth() + 1, //月份 
        "d+": this.getDate(), //日 
        "h+": this.getHours(), //小时 
        "m+": this.getMinutes(), //分 
        "s+": this.getSeconds(), //秒 
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度 
        "S": this.getMilliseconds() //毫秒 
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o) {
        if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    }
    return fmt;
}

function getDom(content, markControl) {
    if (markControl.option.staticServer != undefined) {
        content = content.replace(/{staticServer}/g, markControl.option.staticServer);
    }
    return $(content);
}

function isArray(obj) {
    return obj != undefined && Object.prototype.toString.call(obj) === '[object Array]';
}