Function.prototype.inherits = function(parentCtor) {
  function tempCtor() {};
  tempCtor.prototype = parentCtor.prototype;
  this.superClass_ = parentCtor.prototype;
  this.prototype = new tempCtor();
  this.prototype.constructor = this;
};

var pt = {};
pt.RequestManager = function(id, reqObj) {
  this.id = id;
  this.reqObj = reqObj;
};

pt.RequestManager.start = function(id) {
  if (id == '' || id == undefined) {
    return;
  } else {
    var reqObj = {
      'self': {
        'type': 'getPerson',
        'userId': id,
      },
      'friends' : {
        'type': 'getPeople',
        'idSpec': {'userId': id, 'groupId': 'FRIENDS'}
      },
      'activity' : {
        'type': 'getActivity',
        'idSpec': {'userId': id, 'groupId': 'SELF'}
      },
      'appdata' : {
        'type': 'getAppData',
        'idSpec': {'userId': id, 'groupId': 'SELF'},
        'key': 'example_key'
      }
    };
    var rm = new pt.RequestManager(id, reqObj);
    rm.ignite(function(response) {
      var table = $('<table border="1" cellpadding="0" cellspacing="2" />');
      var tr = $('<tr />');
      var rmBtn = $('<input type="button" value="remove" />').click(function(e) {
        $(e.target).parents('table').remove();
      });
      var idTd = $('<strong>'+id+'</strong>');
      tr.append('<td width="200" bgcolor="gray" />');
      tr.find('td').append(idTd).append($('<br />')).append(rmBtn);
      $.each(reqObj, function(title) {
        if (reqObj[title].type) {
          var req = this;
          var result = response.get(title);
          var td = $('<td width="200"><strong>'+title+': </strong></td>');
          if (result.hadError()) {
            this.request.errorCode = result.getErrorCode();
            this.request.errorMessage = result.getErrorMessage();
            td.append(this.request.errorMessage);
          } else {
            this.request.result = result.getData();
          }
          var button = $('<input type="button" value="visualize" />');
          button.click(function() {
            $('#result').empty();
            var html = req.request.Visualize();
            if (html.find('tbody').length == 0) {
              html.append($('<span style="color:red;">No results</span>'));
            }
            $('#result').html(html);
            gadgets.window.adjustHeight();
          });
          td.append(button);
          tr.append(td);
        }
      });
      $('#new').prepend(table.append(tr));
      gadgets.window.adjustHeight();
    });
  }
};

pt.RequestManager.prototype.ignite = function(callback) {
  var dataReq = opensocial.newDataRequest();
  var _self = this;
  $.each(this.reqObj, function(title) {
    var obj = _self.reqObj[title];
    switch(obj.type) {
      case 'getPerson':
        var req = new pt.PersonRequest(dataReq, obj.userId);
        break;
      case 'getPeople' :
        var req = new pt.PeopleRequest(dataReq, obj.idSpec);
        break;
      case 'getActivity' :
        var req = new pt.ActivityRequest(dataReq, obj.idSpec);
        break;
      case 'getAppData' :
        var req = new pt.AppDataRequest(dataReq, obj.idSpec, obj.key);
        break;
      case 'putAppData' :
        var req = new pt.AppDataRequest(dataReq, obj.idSpec, obj.key);
        break;
      default :
        var req = null;
        break;
    };
    if (req != null) {
      _self.reqObj[title].request = req;
      if (obj.type == 'putAppData') {
        dataReq.add(req.putRequestObject() , title);
      } else {
        dataReq.add(req.getRequestObject(), title);
      }
    }
  });
  dataReq.send(callback);
};

/** Abstract Object **/
pt.Request = function() {
  this.dataReq = null;
  this.result = null;
  this.errorCode = null;
  this.errorMessage = null;
};
pt.Request.prototype.getRequestObject = function() {};
pt.Request.prototype.Visualize = function() {};

/** Person Request Object **/
pt.PersonRequest = function(dataReq, userId) {
  pt.Request.call(this);
  this.dataReq = dataReq;
  this.userId = userId;
};

pt.PersonRequest.inherits(pt.Request);
pt.PersonRequest.prototype.getRequestObject = function() {
  var params = {};
  if (opensocial.getEnvironment().getDomain() != 'myspace.com') {
    var env = opensocial.getEnvironment();
    params[opensocial.DataRequest.PeopleRequestFields.MAX] = 1000;
    params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [];
    $.each(opensocial.Person.Field, function(title) {
      if (env.supportsField(opensocial.Environment.ObjectType.PERSON, opensocial.Person.Field[title])) {
        params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS].push(opensocial.Person.Field[title]);
      }
    });
  }
  return this.dataReq.newFetchPersonRequest(this.userId, params);
};

pt.PersonRequest.prototype.Visualize = function() {
  var html = $('<table border="1" cellpadding="0" />');
  var env = opensocial.getEnvironment();
  var _self = this;
  if (this.result) {
    $.each(opensocial.Person.Field, function(title) {
      if (!title.match(/__$/)) {
        if (env.supportsField(opensocial.Environment.ObjectType.PERSON, opensocial.Person.Field[title])) {
          var param = _self.result.getField(this);
          param = param == undefined ? '--' : param;
          param = title == 'THUMBNAIL_URL' ? '<img src="'+param+'" />' : param;
          if (typeof param == 'object') {
            console.info(param);
          }
          html.append($('<tr />').html('<td width="150">'+this+'</td><td width="200">'+param+'</td>'));
        } else {
          html.append($('<tr />').html('<td width="150">'+this+'</td><td width="200"><span style="color:red;">Not Supported.</span></td>'));
        }
      }
    });
  }
  return html;
};

/** People Request Object **/
pt.PeopleRequest = function(dataReq, idSpec) {
  pt.Request.call(this);
  this.dataReq = dataReq;
  this.idSpec = idSpec;
  this.result = null;
};

pt.PeopleRequest.inherits(pt.Request);
pt.PeopleRequest.prototype.getRequestObject = function() {
  var params = {};
  var env = opensocial.getEnvironment();
  params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS] = [];
  $.each(opensocial.Person.Field, function(title) {
    if (env.supportsField(opensocial.Environment.ObjectType.PERSON, opensocial.Person.Field[title])) {
      params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS].push(opensocial.Person.Field[title]);
    }
  });
  return this.dataReq.newFetchPeopleRequest(opensocial.newIdSpec(this.idSpec, params));
};

pt.PeopleRequest.prototype.Visualize = function() {
  var html = $('<table border="1" cellpadding="0" cellspacing="0" />');
  this.result.each(function(person) {
    var name = person.getDisplayName();
    var id = person.getId();
    var thumbnail = person.getField(opensocial.Person.Field.THUMBNAIL_URL);
    html.append($('<tr />').html('<td width="150"><strong>'+name+'</strong><br/>'+id+'</td><td width="200"><img src="'+thumbnail+'" /></td>'));
  });
  return html;
};

/** Activity Request Object **/
pt.ActivityRequest = function(dataReq, idSpec) {
  pt.Request.call(this);
  this.dataReq = dataReq;
  this.idSpec = idSpec;
};

pt.ActivityRequest.inherits(pt.Request);
pt.ActivityRequest.prototype.getRequestObject = function() {
  return this.dataReq.newFetchActivitiesRequest(opensocial.newIdSpec(this.idSpec));
};

pt.ActivityRequest.prototype.Visualize = function() {
  var input = $('<input type="button" value="add activity" />');
  var _self = this;
  input.click(function() {_self.AddActivity()});
  var html = $('<table border="1" cellpadding="0" cellspacing="0" />');
  html.prepend(input);
  var count = 0;
  if (this.result) {
    this.result.each(function(activity) {
      var str = gadgets.util.unescapeString(activity.getField(opensocial.Activity.Field.TITLE));
      html.append($('<tr />').html('<td width="150"><strong>'+(count++)+'</strong></td><td width="200">'+str+'</td>'));
    });
  }
  return html;
};

pt.ActivityRequest.prototype.AddActivity = function() {
  var params = {};
  params[opensocial.Activity.Field.TITLE] = 'Eiji is experimenting Activity';
  var act = opensocial.newActivity(params);
  opensocial.requestCreateActivity(act, opensocial.CreateActivityPriority.HIGH, function(response) {
    if (response.hadError()) {
      $('#result').html('failed adding activity<br>'+response.getErrorMessage());
    } else {
      $('#result').html('added activity');
    }
  });
};

/** AppData Request Object **/
pt.AppDataRequest = function(dataReq, idSpec, key) {
  pt.Request.call(this);
  this.dataReq = dataReq;
  this.idSpec = idSpec;
  this.userId = idSpec.userId;
  this.key = key;
};

pt.AppDataRequest.inherits(pt.Request);
pt.AppDataRequest.prototype.getRequestObject = function() {
  return this.dataReq.newFetchPersonAppDataRequest(opensocial.newIdSpec(this.idSpec), this.key);
};

pt.AppDataRequest.prototype.putRequestObject = function() {
  var data = {'test':'This is <a href="http://home.goo.ne.jp/">test</a> request'};
  data = gadgets.json.stringify(data);
  return this.dataReq.newUpdatePersonAppDataRequest(this.userId, this.key, data);
};

pt.AppDataRequest.prototype.Visualize = function() {
  var input = $('<input type="button" value="add appdata" />');
  var _self = this;
  input.click(function() {
    var reqObj = {
      'appdata': {
        'type': 'putAppData',
        'idSpec': {'userId': _self.userId, 'groupId': 'SELF'},
        'key': 'example_key'
      }
    };
    var rm = new pt.RequestManager(_self.userId, reqObj);
    rm.ignite(function(response) {
      var result = response.get('appdata');
      if (result.hadError()) {
        $('#result').html('failed adding appdata<br>'+result.getErrorMessage());
      } else {
        $('#result').html('added appdata');
      }
    });
  });
  var html = $('<table border="1" cellpadding="0" cellspacing="0" />');
  html.prepend(input);
  var count = 0;
  if (this.result) {
    $.each(this.result, function(key, val) {
      var str = gadgets.util.unescapeString(val['example_key']);
//    var str = gadgets.json.parse(json);
      html.append($('<tr />').html('<td width="150"><strong>'+(count++)+'</strong></td><td width="200">'+str+'</td>'));
    });
  }
  return html;
};

(function() {
  pt.RequestManager.start('OWNER');
  pt.RequestManager.start('VIEWER');
})();

