function $(id) {
  return document.getElementById(id);
}

function $T(id, tag) {
  return $(id).getElementsByTagName(tag);
}
function textBoxSelect(item, from, to) {
  if (item.setSelectionRange) {
    // Mozilla/Firefox
    item.setSelectionRange(from, to);
  } else if (item.createTextRange) {
    // IE
    var range = item.createTextRange();
    range.moveStart("character", from);
    range.moveEnd("character", to - item.value.length);
    range.select();
  };
};
function addEvent(obj, type, fn) {
  if (obj.addEventListener) {
    if (type == 'mousewheel') {
      type = 'DOMMouseScroll';
    };

    obj.addEventListener( type, fn, false );
  } else if (obj.attachEvent) {
    obj["e"+type+fn] = fn;
    obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
    obj.attachEvent( "on"+type, obj[type+fn] );
  }
}

function removeEvent(obj, type, fn) {
  if (obj.removeEventListener) {
    obj.removeEventListener( type, fn, false );
  } else if (obj.detachEvent) {
    obj.detachEvent( "on"+type, obj[type+fn] );
    obj[type+fn] = null;
    obj["e"+type+fn] = null;
  }
}
Question.prototype = new Object();
Question.prototype.getTitle = Question_getTitle;
Question.prototype.setTitle = Question_setTitle;

Question.create = function(title) {
  var question = new Question();
  question.setTitle(title);
  return question;
}

function Question() {
  this._title = '';
}

function Question_getTitle() {
  return this._title;
}
function Question_setTitle(title) {
  this._title = title;
}QuestionGroup.prototype = new Object();
QuestionGroup.prototype.addQuestion = QuestionGroup_addQuestion;
QuestionGroup.prototype.deleteQuestion = QuestionGroup_deleteQuestion;
QuestionGroup.prototype.getQuestionIndex = QuestionGroup_getQuestionIndex;
QuestionGroup.prototype.getQuestions = QuestionGroup_getQuestions;
QuestionGroup.prototype.getTitle = QuestionGroup_getTitle;
QuestionGroup.prototype.setTitle = QuestionGroup_setTitle;

QuestionGroup.create = function(title) {
  var group = new QuestionGroup();
  group.setTitle(title);
  return group;
}

function QuestionGroup() {
  this._questions = [];
  this._title = '';
}

function QuestionGroup_addQuestion(q) {
  this._questions.push(q);
  return q;
}

function QuestionGroup_deleteQuestion(q) {
  var index = this.getQuestionIndex(q);
  if (index == null) {
    return false;
  };

  this._questions.splice(index, 1);
  return true;   
}

function QuestionGroup_getQuestionIndex(q) {
  for (var i=0; i<this._questions.length; i++) {
    if (this._questions[i] == q) {
      return i;
    };
  };
  return null;
}

function QuestionGroup_getQuestions() {
  return this._questions;
}

function QuestionGroup_getTitle(title) {
  return this._title;
}
function QuestionGroup_setTitle(title) {
  this._title = title;
}// #REQUIRE: dom/helpers.js
// #REQUIRE: gui/select.js
// #REQUIRE: events/core.js

// #REQUIRE: classes/question.js
// #REQUIRE: classes/question.group.js

var page = new Object();

// ------

page.m = new Object();
page.m._currentQuestion = null;
page.m._currentGroup = null;
page.m._groups = [];

page.m.addGroup = function(g) {
  this._groups.push(g);
  return g;
}

page.m.deleteGroup = function(g) {
  var index = this.getGroupIndex(g);
  if (index == null) {
    return false;
  };

  this._groups.splice(index, 1);
  return true; 
}

page.m.deleteQuestion = function(q) {
  for (var i=0; i<this._groups.length; i++) {
    if (this._groups[i].deleteQuestion(q)) {
      return true;
    };
  };

  return false;
}

page.m.getCurrentGroup = function() {
  return this._currentGroup;
}

page.m.getCurrentQuestion = function() {
  return this._currentQuestion;
}

page.m.getGroupIndex = function(g) {
  for (var i=0; i<this._groups.length; i++) {
    if (this._groups[i] == g) {
      return i;
    };
  };
  return null;
}

page.m.getGroups = function() {
  return this._groups;
}

page.m.setCurrentGroup = function(g) {
  this._currentGroup = g;
}

page.m.setCurrentQuestion = function(q) {
  this._currentQuestion = q;
}

// ------

page.v = new Object();

page.v.clear = function() {
  this.getDataContainer().innerHTML = '';
}

page.v.drawGroup = function(container, g) {
  var groupContainer = document.createElement('DIV');

  groupContainer.className = 'question-group';

  var groupHeader = document.createElement('H1');
  if (!page.m.getCurrentQuestion() && page.m.getCurrentGroup() == g) {
    groupHeader.className = 'question-group-header-selected';
  } else {
    groupHeader.className = 'question-group-header';
  };

  var controlsBlock = document.createElement('DIV');
  controlsBlock.className = 'controls-block';
  var deleteButton = document.createElement('IMG');
  deleteButton.src = 'images/delete.gif';
  addEvent(deleteButton, 'click', function() { page.c.onDeleteGroup(g) });
  controlsBlock.appendChild(deleteButton);
  groupHeader.appendChild(controlsBlock);

  groupHeader.appendChild(document.createTextNode(g.getTitle()));

  groupContainer.appendChild(groupHeader);

  var questions = g.getQuestions();
  var numQuestions = questions.length;
  for (var i=0; i<numQuestions; i++) {
    this.drawQuestion(groupContainer, questions[i]);
  };

  addEvent(groupContainer, 'click', function() { page.c.onSelectGroup(g) });

  container.appendChild(groupContainer);
}

page.v.drawQuestion = function(container, q) {
  var questionContainer = document.createElement('DIV');
  if (page.m.getCurrentQuestion() == q) {
    questionContainer.className = 'question-selected';
  } else {
    questionContainer.className = 'question';
  };

  var controlsBlock = document.createElement('DIV');
  controlsBlock.className = 'controls-block';
  var deleteButton = document.createElement('IMG');
  deleteButton.src = 'images/delete.gif';
  addEvent(deleteButton, 'click', function() { page.c.onDeleteQuestion(q) });
  controlsBlock.appendChild(deleteButton);
  questionContainer.appendChild(controlsBlock);

  questionContainer.appendChild(document.createTextNode(q.getTitle()));

  addEvent(questionContainer, 'click', function() { page.c.onSelectQuestion(q) });

  container.appendChild(questionContainer);
}

page.v.getDataContainer = function() {
  return $('survey-data');
}

page.v.prepareNewInput = function() {
  var text = $('controls-text');
  text.focus();

  var currentQuestion = page.m.getCurrentQuestion();
  if (currentQuestion) {
    text.value = currentQuestion.getTitle();
  } else {
    var currentGroup = page.m.getCurrentGroup();
    if (currentGroup) {
      text.value = currentGroup.getTitle();
    };
  };

  textBoxSelect(text, 0, text.value.length);
}

page.v.redraw = function() {
  this.clear();

  var groups = page.m.getGroups();
  var numGroups = groups.length;
  for (var i=0; i < numGroups; i++) {
    this.drawGroup(this.getDataContainer(), groups[i]);
  };
}

// ------

page.c = new Object();

page.c.getControlsText = function() {
  return $('controls-text').value.replace(/^\s+/, '').replace(/\s+$/, '');
}

page.c.onDeleteGroup = function(g) {
  if (!confirm('Do you really want to delete this group and all questions in this group?\nThis operation cannot be undone!')) {
    return;
  };

  page.m.deleteGroup(g);
  page.m.setCurrentGroup(null);
  page.v.redraw();
  page.v.prepareNewInput();
}

page.c.onDeleteQuestion = function(q) {
  if (!confirm('Do you really want to delete this question?\nThis operation cannot be undone!')) {
    return;
  };

  page.m.deleteQuestion(q);
  page.m.setCurrentQuestion(null);
  page.v.redraw();
  page.v.prepareNewInput();
}

page.c.onNewGroup = function() {
  var title = this.getControlsText();

  if (title == '') {
    alert('Please enter non-empty group title!');
    return;
  };

  page.m.setCurrentGroup(page.m.addGroup(QuestionGroup.create(title)));
  page.v.redraw();
  page.v.prepareNewInput();
}

page.c.onNewQuestion = function() {
  if (page.m.getCurrentGroup() == null) {
    alert('Please select existing question group or create one before adding questions.');
    return;
  };

  var title = this.getControlsText();

  if (title == '') {
    alert('Please enter non-empty question text!');
    return;
  };

  page.m.setCurrentQuestion(page.m.getCurrentGroup().addQuestion(Question.create(title)));
  page.v.redraw();
  page.v.prepareNewInput();
}

page.c.onSave = function() {
  if (!confirm('Save all changes and stop editing this survey?')) {
    return;
  };

  var form = $('survey-form');

  var hidden = document.createElement('INPUT');
  hidden.setAttribute('type', 'hidden');
  hidden.setAttribute('name', 'name');
  hidden.setAttribute('value', $('survey-title').value);
  form.appendChild(hidden);

  var groups = page.m.getGroups();
  var numGroups = groups.length;

  for (var i=0; i<numGroups; i++) {
    var hidden = document.createElement('INPUT');
    hidden.setAttribute('type', 'hidden');
    hidden.setAttribute('name', 'item_names[]');
    hidden.setAttribute('value', groups[i].getTitle());
    form.appendChild(hidden);

    var hidden = document.createElement('INPUT');
    hidden.setAttribute('type', 'hidden');
    hidden.setAttribute('name', 'item_types[]');
    hidden.setAttribute('value', 1);
    form.appendChild(hidden);

    var questions = groups[i].getQuestions();
    var numQuestions = questions.length;
    for (var j=0; j<numQuestions; j++) {
      var hidden = document.createElement('INPUT');
      hidden.setAttribute('type', 'hidden');
      hidden.setAttribute('name', 'item_names[]');
      hidden.setAttribute('value', questions[j].getTitle());
      form.appendChild(hidden);

      var hidden = document.createElement('INPUT');
      hidden.setAttribute('type', 'hidden');
      hidden.setAttribute('name', 'item_types[]');
      hidden.setAttribute('value', 0);
      form.appendChild(hidden);
    };
  };

  form.submit();
}

page.c.onSelectGroup = function(g) {
  page.m.setCurrentGroup(g);
  page.m.setCurrentQuestion(null);
  page.v.redraw();
  page.v.prepareNewInput();
}

page.c.onSelectQuestion = function(q) {
  page.m.setCurrentQuestion(q);
  page.v.redraw();
  page.v.prepareNewInput();
}

page.c.onUpdate = function() {
  var title = this.getControlsText();

  if (title == '') {
    alert('Please enter non-empty text!');
    return;
  };

  var item = page.m.getCurrentQuestion() || page.m.getCurrentGroup();
  item.setTitle(title);
  page.v.redraw();
  page.v.prepareNewInput();
}
