// JavaScript Document

/* Showing Loading Progress of Page and Data */

var ProgressBar = ElementWrapper.extend({

    FINISHED_DOT_IMG: './img/blue1x1.png',
    SLIDER_IMG: './img/blue_gradient30x1.gif',
    SRC_IMG: './img/transp1x1.gif',
    
    UNIT_FACTOR: 1000,
    STEP_WIDTH: 50,
    REFRESH_PERIOD: 100, 

	construct: 
		function(imgElementId) {
			arguments.callee.$.construct.call(this, imgElementId); // call parent constructor
			this._loadingInterval = null;
			this._startTime = null;
			this._timeTaken = 0;
			this.element.src = this.SRC_IMG;
			this.element.style.backgroundImage = "url('" + this.SLIDER_IMG + "')";
		},
		
	onStart:
	   function(infoPrefix, infoPostfix) {
	       var infoPrefix = infoPrefix || "";
	       var infoPostfix = infoPostfix || "";
           this._startTime = new Date();
           function updateLoadingStats(c) {
                c._timeTaken = ((new Date() - c._startTime) / c.UNIT_FACTOR);
                c.element.alt = infoPrefix + c._timeTaken + infoPostfix;
                c.element.title = infoPrefix + c._timeTaken + infoPostfix;
                c.element.style.backgroundPosition = 
                    ((c._timeTaken % c.STEP_WIDTH) * 
                     (c.element.offsetWidth / c.STEP_WIDTH)) + 'px 0';
           }
           var this_ = this;
           this._loadingInterval = setInterval(function(){updateLoadingStats(this_)}, this.REFRESH_PERIOD);
       },
       
	onComplete:
	   function(infoPrefix, infoPostfix) {
	       var infoPrefix = infoPrefix || '';
	       var infoPostfix = infoPostfix || '';
	       if (this._loadingInterval) clearInterval(this._loadingInterval);
           this.element.alt = infoPrefix + this._timeTaken + infoPostfix;
           this.element.title = infoPrefix + this._timeTaken + infoPostfix;
           this.element.style.backgroundImage = "url('" + this.FINISHED_DOT_IMG + "')";
           this.element.style.backgroundRepeat = 'repeat';
           this.element.style.backgroundPosition = '0 0';
       },
       
    run:
        function(infoPrefix, infoPostfix) {
            this.onStart(infoPrefix, infoPostfix);
        },
        
    finish:
        function(infoPrefix, infoPostfix) {
            this.onComplete(infoPrefix, infoPostfix);
        }  
    
});

var AbstractControllableElm = ElementWrapper.extend({
    
    construct:
        function(elementId, isActive, isHidden) {
            arguments.callee.$.construct.call(this, elementId);
            this._isActive = isActive;            
            this._isHidden = isHidden;
            this._updateStyle();
        },
        
    _updateStyle:
        function() {
            var appStyleStr = this._getStyleToAppend();
            var appendingStyle = (appStyleStr && (appStyleStr.length > 0)) ? ' ' + appStyleStr : '';
            this.element.className = this._getClassName() + appendingStyle +                         
                        (this._isActive ? ' active' : ' inactive') +
                        (this._isHidden ? ' hidden' : '');
        },        
        
    activate:
        function() {
            this._isActive = true;
            this._updateStyle();            
        },
        
    deactivate:
        function() {
            this._isActive = false;
            this._updateStyle();
        },
        
    hide:
        function() {
            this._isHidden = true;
            this._updateStyle();
        },
        
    show:
        function() {
            this._isHidden = false;
            this._updateStyle();
        },
        
    switchState:
        function(isActive, isHidden) {
            this._isActive = isActive;
            this._isHidden = isHidden;
            this._updateStyle();
        },
        
    _getClassName:
        function() {
            return '';
        },
        
    _getStyleToAppend:
        function() {
            return '';
        }        
    

});

var Mark = AbstractControllableElm.extend({

    CLASS_NAME: 'mark',

    ACCEPT_MARK_SRC: 'v-mark',
    DENY_MARK_SRC: 'x-mark',
    UNKNOWN_MARK_SRC: 'q-mark',
    INACTIVE_MARK_SRC: '_-mark',
    
    CREATE_ACT_SRC: '(!)-act',
    JOIN_ACT_SRC: '(+)-act',
    LEAVE_ACT_SRC: '(-)-act',
    
    SRC_PREFIX: './img/',
    MARKS_EXT: 'png',
    SMALL_POSTFIX: '-small',
    
    construct:
        function(imgElementId, isActive, isHidden) {
            arguments.callee.$.construct.call(this, imgElementId, isActive, isHidden);
            this._isSmall = false;
            this.makeUnknown();
        }, 
        
    setSmall:
        function(isSmall) {
            this._isSmall = isSmall;
        },

    makeAccept:
        function() {
            this.element.src = this.SRC_PREFIX + this.ACCEPT_MARK_SRC + 
                        (this._isSmall ? this.SMALL_POSTFIX: '') + 
                        '.' + this.MARKS_EXT;
        },
        
    makeDeny:
        function() {
            this.element.src = this.SRC_PREFIX + this.DENY_MARK_SRC + 
                        (this._isSmall ? this.SMALL_POSTFIX: '') + 
                        '.' + this.MARKS_EXT;
        },
        
    makeUnknown:
        function() {
            this.element.src = this.SRC_PREFIX + this.UNKNOWN_MARK_SRC + 
                        (this._isSmall ? this.SMALL_POSTFIX: '') + 
                        '.' + this.MARKS_EXT;
        },
        
    makeInactive:
        function() {
            this.element.src = this.SRC_PREFIX + this.INACTIVE_MARK_SRC + 
                        (this._isSmall ? this.SMALL_POSTFIX: '') + 
                        '.' + this.MARKS_EXT;
        }, 
        
    makeCreate:
        function() {
            this.element.src = this.SRC_PREFIX + this.CREATE_ACT_SRC + 
                        '.' + this.MARKS_EXT;
        },
        
    makeJoin:
        function() {
            this.element.src = this.SRC_PREFIX + this.JOIN_ACT_SRC + 
                        '.' + this.MARKS_EXT;
        },

    makeLeave:
        function() {
            this.element.src = this.SRC_PREFIX + this.LEAVE_ACT_SRC + 
                        '.' + this.MARKS_EXT;
        },                
        
    _getClassName:
        function() {
            return this.CLASS_NAME;
        }                     

});

var Step = ElementWrapper.extend({

    CLASS_NAME: 'step',
    
    construct:
        function(fromStage, toStage, switchedOn) {
            var stepId = fromStage + (toStage ? ('-to-' + toStage) : '');
            arguments.callee.$.construct.call(this, stepId);
            this._switchedOn = switchedOn;
            this._newLineElm = document.getElementById(stepId + '-nl');
            this._updateStyle();
        },
        
    _updateStyle:
        function() {
            this.element.className = this.CLASS_NAME + (this._switchedOn ? ' active' : ' inactive');
            if (this._newLineElm) this._newLineElm.className = this.CLASS_NAME + (this._switchedOn ? ' active' : ' inactive') + ' newline';
        },
    
    switchOn:
        function() {
            this._switchedOn = true;
            this._updateStyle();            
        },
        
    switchOff:
        function() {
            this._switchedOn = false;
            this._updateStyle();
        },
        
    switchState:
        function(switchOn) {
            this._switchedOn = switchOn;
            this._updateStyle();
        }
        
});

var ActBlock = AbstractControllableElm.extend({

    CLASS_NAME: 'actblock',
    
    construct:
        function(elementId, alignment, controlledElms, state, isHidden) {
            //console.log(elementId, document.getElementById(elementId));
            this._alignment = alignment; // centered | right | middle | left  
            this._state = (state == null) ? 'prepared' : state; // prepared | inactive | active
            this._controlledElms = [];         
            for (var elmIdx in controlledElms) {
                var cElmId = controlledElms[elmIdx];
                //this._controlledElms.push(document.getElementById(controlledElms[elmIdx]));
                this._controlledElms[cElmId] = document.getElementById(cElmId);
                // console.log('> ', cElmId, document.getElementById(cElmId));
            }                  
            arguments.callee.$.construct.call(this, elementId, (state == 'active'), isHidden); 
        },
        
    _updateStyle:
        function() {
            var appStyleStr = this._getStyleToAppend();
            var appendingStyle = (appStyleStr && (appStyleStr.length > 0)) ? ' ' + appStyleStr : '';
            this.element.className = this._getClassName() + appendingStyle +                         
                        ' ' + this._state + (this._isHidden ? ' hidden' : '');
        },    
        
    prepare:
        function() {
            this._state = 'prepared';
            this._updateStyle();
        },
        
    switchState:
        function(isActive, isHidden) {
            this._state = isActive ? 'active' : 'inactive';
            this._isHidden = isHidden;
            this._updateStyle();
        },        
        
    /* replaceWith:
        function(actBlock) {
            this.disable();
            this.hide();
            actBlock.
        }, */
        
    _getClassName:
        function() {
            return this.CLASS_NAME;
        },
        
    setClassName:
        function(className) {
            this.CLASS_NAME = className;
        },        
        
    _getStyleToAppend:
        function() {
            return this._alignment/* TODO: + (this._isPrepared ? ' prepared' : '') */;
        },
        
    activate:
        function() {
            // arguments.callee.$.activate.call(this);            
            this._state = 'active';
            this._updateStyle(); 
            for (var elmIdx in this._controlledElms) {                
                this._controlledElms[elmIdx].disabled = false;
                this._controlledElms[elmIdx].className = 'active';
            }
        },
        
    deactivate:
        function() {
            // arguments.callee.$.deactivate.call(this);
            this._state = 'inactive';
            this._updateStyle();
            for (var elmIdx in this._controlledElms) {
                this._controlledElms[elmIdx].disabled = true;
                this._controlledElms[elmIdx].className = 'inactive';
            }
        },
        
    getControlledElms:
        function() {
            return this._controlledElms;
        }
    
});
