/* -----------------------------------------------------------------------------

buttons.js uses:
  inheritance.js
  context.js
  
------------------------------------------------------------------------------- */

var Button = Class.extend( Component, {

  initialize: function ( componentKey ) {

    this.parent( componentKey );
    
    this.element = $("#" + componentKey );

    var controller = this;

    this.element.click( function () {

      controller.context.notify( "click", { type: controller.componentKey } );
    
    });

  },

  show: function () {

    //this.element.show();
    this.element.css("display","block");

  },

  hide: function () {

    //this.element.hide();
    this.element.css("display","none");

  },

  active: function () {

    //this.element.removeClass("gray");
    var bgimg = this.element.css("background-image");
    bgimg = bgimg.replace(/_gray/,"");
    this.element.css("background-image",bgimg);
    this.show();

  },

  inactive: function () {

    //this.element.addClass("gray");
    var bgimg = this.element.css("background-image");
    if ( !bgimg.match(/_gray/)) {
      bgimg.match(/^(.*)\.(.*)$/);
      bgimg = RegExp.$1 + "_gray." + RegExp.$2;
      this.element.css("background-image",bgimg);
    }
    this.show();
  }

});

var ReplayTalkButton = Class.extend( Button, {

    initialize: function ( componentKey ) {

      this.parent( componentKey );

    },

    turnSkip: function () {

      //this.element.addClass("skip");
      var bgimg = this.element.css("background-image");
      bgimg = bgimg.replace(/replay/,"skip");
      this.element.css("background-image",bgimg);
      this.show();

    },

    turnReplay: function () {

      //this.element.removeClass("skip");
      var bgimg = this.element.css("background-image");
      bgimg = bgimg.replace(/skip/,"replay");
      this.element.css("background-image",bgimg);
      this.show();

    }

});

var GuessButton = Class.extend( Button, {

    initialize: function ( componentKey ) {

      this.parent( componentKey );
      this.isCheked = false;
      
    },

    check: function () {

      //this.element.addClass("checked");
      var bgimg = this.element.css("background-image");
      bgimg.match(/\./);
      bgimg = RegExp.leftContext + "_checked." + RegExp.rightContext;
      this.element.css("background-image",bgimg);
      this.isChecked = true;

    },

    uncheck: function () {

      //this.element.removeClass("checked");
      var bgimg = this.element.css("background-image");
      bgimg = bgimg.replace(/_checked/,"");
      this.element.css("background-image",bgimg);
      this.isChecked = false;

    },

    toggle: function () {

      if ( this.isChecked ) {

        this.uncheck();

      }
      else {

        this.check();

      }

    }

});

var ShowSolutionButton = Class.extend( Button, {

    initialize: function ( componentKey ) {

      this.parent( componentKey );
      this.state = false;

    },

    toggle: function () {

      if (this.state) {

        this.turnHide();
        this.state = false;

      }
      else {

        this.turnShow();
        this.state = true;

      }

    },

    turnHide: function () {

      //this.element.removeClass("hide");
      var bgimg = this.element.css("background-image");
      bgimg = bgimg.replace(/hide/,"show");
      this.element.css("background-image",bgimg);
      this.show();

    },

    turnShow: function () {

      //this.element.addClass("hide");
      var bgimg = this.element.css("background-image");
      bgimg = bgimg.replace(/show/,"hide");
      this.element.css("background-image",bgimg);
      this.show();

    }

});

var ViewTextButton = Class.extend( Button, {

    initialize: function ( componentKey ) {

      this.parent( componentKey );
      this.state = false;

    },

    toggle: function () {

      if (this.state) {

        this.turnText();
        this.state = false;

      }
      else {

        this.turnQuestion();
        this.state = true;

      }

    },

    turnText: function () {

      //this.element.removeClass("question");
      var bgimg = this.element.css("background-image");
      bgimg = bgimg.replace(/question/,"text");
      this.element.css("background-image",bgimg);
      this.show();

    },

    turnQuestion: function () {

      //this.element.addClass("question");
      var bgimg = this.element.css("background-image");
      bgimg = bgimg.replace(/text/,"question");
      this.element.css("background-image",bgimg);
      this.show();

    }

});

var DebugButton = Class.extend( Button, {

     initialize: function ( componentKey ) {

      this.parent( componentKey );
      this.element.css("border","1px dotted #999");
      this.element.css("cursor","pointer");

    }

});


var Timer = Class.extend( Component, {


  //arguments -----------------------------------------------------------------
  isActive      : true,
  callbackFunc  : function(){ alert("[WARNNING] callbackFunc is not defined.") },
  beat          : 500,          //default 500msec
  startTime     : 5000,         //default 5sec
  endDate       : undefined,
  nowTime       : undefined,
  prevPauseTime : undefined,
  endTime       : undefined,
  baseTimer     : undefined,


  //methods -------------------------------------------------------------------
  initialize: function( componentKey, args ){

    this.parent( "timer" );
    this.element = $("#timer");

    if(args){

      this.isActive       = args.isActive;

      this.callbackFunc   = args.callbackFunc;

      this.beat           = args.beat;
      this.startTime      = Number(args.startTime);

      this.endDate        = new Date();
      this.nowTime        = this.endDate.getTime();
      this.endDate.setTime(this.nowTime+this.startTime);
      this.endTime        = this.endDate.getTime();
      this.prevPauseTime  = this.nowTime;
      this.callbackFunc( this.perseTime(this.startTime) );

      //start baseclock
      var self = this;
      this.baseTimer      = setInterval(
                              function(){
                                self.beatTime();
                              },
                              this.beat
                            );


    }
    else{

      alert("[WARNNING] Init Timer Class require argument");

    }

  },


  show: function () {

    this.element.show();

  },

  hide: function () {

    this.element.hide();

  },


  setStartTime: function(starttime){
    this.startTime = starttime;
  },


  startTimer: function(){

    this.show();
    this.isActive=true;

  },


  pauseTimer: function(){

    this.isActive=false;

  },


  resetTimer: function( startTime ){

    this.startTime = startTime;

    this.endDate        = new Date();
    this.nowTime        = this.endDate.getTime();
    this.prevPauseTime  = this.nowTime;
    this.endDate.setTime(this.nowTime+this.startTime);
    this.endTime        = this.endDate.getTime();
    this.isActive       = false;
    this.callbackFunc( this.perseTime(this.startTime) );

  },


  beatTime: function(){

    var nowDate   = new Date();
    this.nowTime  = nowDate.getTime();

    if( !this.isActive ){

      var tempEndTime     = this.endDate.getTime() + Number( this.nowTime - this.prevPauseTime );
      this.endDate.setTime( tempEndTime );

    }
    else{
      this.show();
    }

    var remainingTime = Number(this.endDate.getTime() - this.nowTime);
    this.callbackFunc( this.perseTime(remainingTime) );
    this.prevPauseTime   = this.nowTime;

  },

  //ミリ秒を00:00:00にパース 
  perseTime: function(msec){

    var tempMark=" ";

    if(msec<0){
      msec = 0-msec;
      tempMark="-";
    }

    var hour	 = this.zeroPadding( Math.floor(msec/1000/60/60) ,2 );
    var min		 = this.zeroPadding( Math.floor(msec/1000/60) ,2 );
    var sec		 = this.zeroPadding( Math.floor(msec/1000)%60 ,2 );

    return tempMark+hour+":"+min+":"+sec;
  },

  //ゼロパディング
  zeroPadding: function(targetNumber,digitNum){
    var tempNum=Math.pow(10,digitNum)+Number(targetNumber);
    tempNum = String(tempNum).slice(1);
    return tempNum;
  },


  finishFunc: function(){
    alert("do nothing");
  }

});



var VolumeController = Class.extend( Component, {

  initialize: function ( componentKey ) {

    this.parent( componentKey );
    this.element = $("#" + componentKey );
    this.isVisible = false;


   },

  show: function () {

    this.element.show();
    this.isVisible = true;

  },

  hide: function () {

    this.element.hide();
    this.isVisible = false;

  },

  toggle: function () {

    if ( this.isVisible ) {

      this.hide();

    }
    else {

      this.show();

    }

  }

});

var QuestionCounter = Class.extend( Component, {

  initialize: function ( componentKey, arg ) {

    this.parent( componentKey );
    this.element = $( "#" + componentKey );
    this.totalQuestionNum = arg.totalQuestionNum;

  },

  change: function ( questionNum ) {

    $("#question_num",this.element).text( questionNum );
    $("#total_question_num",this.element).text( this.totalQuestionNum );
    
  },

  show: function () {

    this.element.show();

  },

  hide: function () {

    this.element.hide();

  }

});


var QuestionReviewCounter = Class.extend( QuestionCounter, {

  initialize: function ( componentKey, arg ) {

    this.parent( componentKey, arg );

  },

  change: function ( questionNum ) {

    this.parent( questionNum );
    this.checkPosition( questionNum );
    
  },

  checkPosition: function ( questionNum ) {

    if ( questionNum == 1) {
      this.context.notify("is_first");
    }
    else if ( questionNum == this.totalQuestionNum ) {
      this.context.notify("is_last");
    }
    else {
      this.context.notify("is_middle");
    }

  }

});

var CountDownTimer = Class.extend( Component, {

  initialize: function ( componentKey, interval, hourElement, minuteElement, secondElement ) {

    this.parent( componentKey );
    
    this.element = $( "#" + componentKey );
    this.hourElement   = this.element.find( "#" + hourElement );
    this.minuteElement = this.element.find( "#" + minuteElement );
    this.secondElement = this.element.find( "#" + secondElement );

    this.interval = interval; // msec
    this.timerId;

    this.remainingTime;
    this.elapse;
    this.lastBeatTime;

    this.isPaused;
    this.isRemaining = true;

    this.isVisible = true;

    this._setUi();

  },

  reset: function ( t ) { // msec

    this.stop();
    this.remainingTime = t;
    this.lastBeatTime = 0;
    this.elapse = 0;
    this.isRemaining = true;

    this._display( this.remainingTime );

  },

  start: function () {

    this.isPaused = false;
  
    if ( !this.timerId ) {

      var self = this;
      this.timerId = setInterval( function(){ self._beat() }, this.interval );

    }

  },

  pause: function () {

    this.isPaused = true;

  },

  stop: function () {

    if ( this.timerId ) {
    
       clearInterval( this.timerId );
    
    }

    this.timerId = false;

  },

  show: function () {

    this.element.show();

  },

  hide: function () {

    this.element.hide();

  },

  toggle: function () {

    if ( this.isVisible ) {

      this.turnHide();
      this.isVisible = false;

    }
    else {

      this.turnShow();
      this.isVisible = true;

    }

  },

  turnHide: function () {
    
    var button = this.element.find("#btn_showtimer");
    var bgimg = button.css("background-image");
    bgimg = bgimg.replace(/hide/,"show");
    button.css("background-image",bgimg);

    this.element.find(".time").css("visibility","hidden");
    this.element.find(".among").css("visibility","hidden");

  },

  turnShow: function () {

    var button = this.element.find("#btn_showtimer");
    var bgimg = button.css("background-image");
    bgimg = bgimg.replace(/show/,"hide");
    button.css("background-image",bgimg);

    this.element.find(".time").css("visibility","visible");
    this.element.find(".among").css("visibility","visible");

  },

  isInTime: function () {

    return this.isRemaining;

  },

  _beat: function () {

    if ( this.lastBeatTime ) {

      var t = new Date();
      this.elapse = t - this.lastBeatTime;
      this.lastBeatTime = t;

    }
    else {

      this.elapse = 0;
      this.lastBeatTime = new Date();

    }

    if ( !this.isPaused ) {


      this.remainingTime = this.remainingTime - this.elapse;

      if ( this.remainingTime > 0 ) {

        this._display( this.remainingTime );

      }
      else {

        this._timeOver();

      }

    }
    else {

      return

    }

  },

  _display: function ( t ) {

    if ( t ) {

      var mark = "";

      if ( t < 0 ) {
      
        t = t * -1;
        mark = "-";
      
      }

      this.hourElement.html  ( mark + ( "0" + Math.floor( t/1000/60/60 ) ).slice(-2) );
      this.minuteElement.html( ( "0" + Math.floor( t/1000/60    ) ).slice(-2) );
      this.secondElement.html( ( "0" + Math.floor( t/1000 )%60    ).slice(-2) );


    }
    else {

      this.hourElement.html  ("00");
      this.minuteElement.html("00");
      this.secondElement.html("00");

    }

  },

  _timeOver: function () {

    this._display( 0 );
    this.stop();
    this.isRemaining = false;

  },

  _setUi: function () {

    var self = this;
    this.element.find( "#btn_showtimer" ).bind( "click", function(){ self.toggle() } );

  }

})

var WritingTimer = Class.extend( CountDownTimer, {

  initialize: function (  componentKey, interval, hourElement, minuteElement, secondElement  ) {

    this.parent(  componentKey, interval, hourElement, minuteElement, secondElement  );
    this.slideController;

  },

  _beat: function () {

    if ( this.lastBeatTime ) {

      var t = new Date();
      this.elapse = t - this.lastBeatTime;
      this.lastBeatTime = t;

    }
    else {

      this.elapse = 0;
      this.lastBeatTime = new Date();

    }

    if ( !this.isPaused ) {

      this.remainingTime = this.remainingTime - this.elapse;

      if ( this.remainingTime < 0 && this.isRemaining ) {

        this._timeOver();

      }
      else {

        this._display( this.remainingTime );

      }

    }
    else {

      return

    }

  },

  _timeOver: function () {

    this.isRemaining = false;
    this.context.notify("timeout");

  }

});

var SpeakingPassageTimer = Class.extend( CountDownTimer, {

  initialize: function (  componentKey, interval, hourElement, minuteElement, secondElement  ) {

    this.parent(  componentKey, interval, hourElement, minuteElement, secondElement  );
    this.slideController;

  },

  start: function ( slideController ) {

    this.parent();
    this.slideController = slideController;

  },

  _timeOver: function () {

    this.parent();
    this.slideController.timeout();

  }

});

