define([
		'Global',
		'User',
		'Patient'
	],
	function (Global, user, Patient) {
		var singleInstance,
			PatientContext = Backbone.Model.extend({
				initialize: function () {
					this.patient = new Patient();
				},
				isValid: function () {
					return this.patient.get('patientIdentifier');
				},
				resume: function (callBackFn) {
                    var that = this;

                    if (this.isValid()) {
                        Global.getUtilities().eventAggregator.trigger('footer');
                        if ($.isFunction(callBackFn)) {
                            callBackFn(that.patient);
                        }
                    } else {
                        this.patient.fetch({
                            url: user.get('user-context').href,
                            success: function (model) {
                                Global.getUtilities().flattenLinks(model);
                                Global.getUtilities().eventAggregator.trigger('footer');
                                if ($.isFunction(callBackFn)) {
                                    callBackFn(model);
                                }
                            },
                            error: function () {
                                if ($.isFunction(callBackFn)) {
                                    callBackFn();
                                }
                            }
                        });
                    }
				},
				createContext: function (options) {
					options = options || {};

					var url = options.url || "",
						callBack = $.isFunction(options.success) ? options.success : function () {
						},
						newPatient = options.patient || {},
						that = this;

					if (newPatient.patientIdentifier) {
						this.patient.set(this.patient.parse(newPatient));
						this.updatePatient(callBack);
					} else {
						this.patient.fetch({
							url: url,
							success: function () {
								that.updatePatient(callBack);
							}
						});
					}
				},
				updatePatient: function (callBack) {
					var payload = this.patient.get('patientIdentifier'),
						url = user.get('user-context').href,
						utilities = Global.getUtilities(),
						that = this;

					this.patient.set({
						patientId: payload.uniqueId,
						patientAssigningAuthority: payload.assigningAuthority
					});
					this.patient.url = url;
					utilities.flattenLinks(this.patient);
					this.patient.save(
						{},
						{
							success: function () {
								if ($.isFunction(callBack)) {
									callBack(that.patient);
								}
							},
							error: function () {
								if ($.isFunction(callBack)) {
									callBack(that.patient);
								}
							}
						}
					);
				},
				reloadPatient: function(){
					var that = this,
						clone = this.patient.clone();

					if(clone.has('patientIdentifier')){
						clone.fetch({
							url: clone.get('self').href
						}).done(function(response){
							that.patient.set(that.patient.parse(response));
							that.trigger('change');
						});
					}
				},
				clearContext: function (options) {
					var url = options && options.url ? options.url : user.get('user-context').href,
						callBack = options && $.isFunction(options.success) ? options.success : function () {
						},
						that = this,
						utilities = Global.getUtilities();

					this.patient.url = url;

					$.ajax({
						type: 'DELETE',
						url: url,
						contentType: "application/json; charset=utf-8",
						dataType: "json",

						success: function (response) {
							that.patient = new Patient();

							if ($.isFunction(callBack)) {
								callBack(response);
							}
						},
						error: function (response) {
							that.patient = new Patient();

							if ($.isFunction(callBack)) {
								callBack(response);
							}
						}
					});
				},
				getPatient: function () {
					return this.patient;
				},
				isDfnInContext: function (dfn) {
					var identifier = this.patient.get('patientIdentifier'),
						patientId = identifier ? identifier.uniqueId : "";
					return dfn === patientId;
				}
			});

		PatientContext.instance = function () {
			if (typeof singleInstance === "undefined") {
				singleInstance = new PatientContext();
			}
			return singleInstance;
		};

		PatientContext.clearInstance = function () {
			singleInstance = undefined;
		};

		return PatientContext;
	}
);