
var github_url = "http://github.com/api/v2/json/repos/show/mymayumayu";
var github_commit = "http://github.com/api/v2/json/commits/list/mymayumayu";
var mutex = 0;
var stack = new Array();
var stack2 = new Array();
var callback_fnc = null;
var callback_fnc2 = null;
var callback_var = null;
var callback_var2 = null;
var repositories = new Object();
var repos_divs = new Array();

function tout() {
  if (mutex > 0) {
    setTimeout(tout, 100);
    return;
  }
  setTimeout(callback_fnc, 10);
}
function tout2() {
  if (mutex > 0) {
    setTimeout(tout2, 100);
    return;
  }
  if (!callback_fnc2) {
    tout();
    return;
  }
  setTimeout(callback_fnc2, 10);
}

function getJSONP(url, success) {
  var ud = '_' + +new Date, script = document.createElement('script'), head = document.getElementsByTagName('head')[0] || document.documentElement;
  while(window[ud]) { ud = '_' + +new Date; }
  
  window[ud] = function(data) {
      head.removeChild(script);
      success && success(data);
  };
  
  script.type = 'text/javascript';
  script.src = url+"?callback="+ud;
  head.appendChild(script);
}

function display_data() {
  repository_all()
}

// secondary processing for commits
// callback_var holds current repository object
// callback_var2 holds current branch name
function process_commit(data) {
  if (!callback_var.commits) {
    callback_var.commits = new Object();
  }
  callback_var.commits[callback_var2] = data;
  mutex--;
}

// process commit for branch on stack2
// current branch name on callback_var2
function process_commits() {
  var branch = stack2.pop();
  if (!branch) {
    callback_fnc2 = null;
    callback_var2 = null;
    tout2();
    return;
  }
  mutex++;
  callback_var2 = branch;
  getJSONP(github_commit + "/" + callback_var.name + "/" + branch, process_commit);
  tout2();
}

// init fetching of commits
// callback_var points to current repository object
// pushes all branch names on stack2
function transcode_commits() {
  var key = stack.pop();
  if (!key) {
    callback_var = null;
    callback_fnc = display_data;
    tout();
    return;
  }
  callback_var = repositories[key];
  callback_fnc2 = process_commits;
  for (i in repositories[key].branches.branches) {
    stack2.push(i); //push all branch names
  }
  tout2();
}

// secondary processing for branches
// current repository object on callback_var
function process_branches(data) {
  callback_var.branches = data;
  mutex--;
}

// secondary processing per repository
// fetch all branches and attach them to repository array
// when stack is empty: init fetching commits, push repository names on stack
function transcode_repos() {
  var repos = stack.pop()
  if (!repos) {
    callback_fnc = transcode_commits;
    for (i in repositories) {
      stack.push(i);
    }
    tout();
    return;
  }
  repositories[repos.name] = repos;
  callback_var = repositories[repos.name];
  mutex++;
  getJSONP(github_url + "/" + repos.name + "/branches", process_branches);
  tout();
}

// push found repositories on stack
// init secondary processing for each repository
function process_all_repos(data) {
  callback_fnc = transcode_repos;
  for (i=data.repositories.length - 1; i>=0; i--) {
    stack.push(data.repositories[i]);
  }
  tout();
}

// init fetching all repositories
function all_repos() {
  getJSONP(github_url, process_all_repos);
}

function loader() {
  all_repos();
  
  create_load();
  hook();
}

