var Finder = {
	
};

Finder.Date = {
    dateToString: function(value) {
        return Finder.Date.prependWithZero(value.getDate()) + '.' + Finder.Date.prependWithZero(value.getMonth() + 1) + '.' + value.getFullYear();
    },
    
    dateToStringDB: function(value) {
        return value.getFullYear() +  '-' + Finder.Date.prependWithZero(value.getMonth() + 1) + '-' + Finder.Date.prependWithZero(value.getDate());
    },
    
    stringToDate: function(value) {
        if (!value) return new Date();
          
//        if (LC_LANG=='ru')
//        {
    	    parts = value.split('.');
    	    for (i=0;i<parts.length; i++) {
        	if (parts[i].charAt(0)=='0') parts[i] = parts[i].substr(1);
    	    }
        
    	    result = new Date(parseInt(parts[2]), parseInt(parts[1])-1, parseInt(parts[0]));
    	    if (result == 'Invalid Date') result = new Date();
    	    return result;
/*    	}
    	else
    	{
    	    parts = value.split('-');
    	    for (i=0;i<parts.length; i++) {
        	if (parts[i].charAt(0)=='0') parts[i] = parts[i].substr(1);
    	    }
        
    	    result = new Date(parseInt(parts[0]), parseInt(parts[2])-1, parseInt(parts[1]));
    	    if (result == 'Invalid Date') result = new Date();
    	    return result;
    	
    	}*/
    },
    
    stringDBToDate: function(value) {
        if (!value) return new Date();
        parts = value.split('-');
        for (i=0;i<parts.length; i++) {
        	if (parts[i].charAt(0)=='0') parts[i] = parts[i].substr(1);
        }
        result = new Date(parseInt(parts[0]), parseInt(parts[1] - 1), parseInt(parts[2]));
        if (result == 'Invalid Date')
            result = new Date();
        return result;
    },
    
    prependWithZero: function(value) {
        value = parseInt(value);
        return (value < 10 ? '0' : '') + value;
    }
};


// finder shield

Finder.Shield = Class.create();
Finder.Shield.prototype = {
	initialize: function(element, shield, options) {
		this.element = $(element);
		this.shield = $(shield);
		this.options = options || {};
		
		this.options.duration = this.options.duration || 0.0;
		this.options.opacity = this.options.opacity || 0.0;
		
		this.showIEFixFrame = this.showIEFixFrame.bind(this);
	},
	
	show: function() {
		if (!this.visible()) 
                    this.appear();
		if (!this.ie_fix_frame && Prototype.Browser.IE && this.shield.getStyle('position') == 'absolute') {
			new Insertion.After(this.shield,
				'<iframe id="' + this.shield.id + '_ie_fix_frame" style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0.5);" src="javascript:false;" frameborder="0" scrolling="no"></iframe>'
			);
			this.ie_fix_frame = $(this.shield.id + '_ie_fix_frame');
		}
		if (this.ie_fix_frame) setTimeout(this.showIEFixFrame, 50);
	},
	
	appear: function() {
	    Position.absolutize(this.shield);
	    Position.clone(this.element, this.shield);
            this.shield.setStyle({cursor: 'progress'});
	    this.shield.visualEffect('appear', {duration: this.options.duration, to: this.options.opacity, queue: {position: 'end', scope: 'finder'}});
	},
	
	showIEFixFrame: function() {
		Position.clone(this.shield, this.ie_fix_frame, {setTop: !this.shield.getStyle('height')});
		this.ie_fix_frame.setStyle({'z-index': 1});
		this.shield.setStyle({'z-index': 2});
		this.ie_fix_frame.show();
	},
	
	hide: function() {
                if(this.shield.visible())
                    this.fade();
		if (this.ie_fix_frame) this.ie_fix_frame.hide();
                this.shield.setStyle({cursor: 'default'});
	},
	
	fade: function() {
		this.shield.visualEffect('fade', {duration: this.options.duration, queue: {position: 'end', scope: 'finder'}});
	},
	
	visible: function() {
		return this.shield.visible();
	}
};


// chain selector

Finder.Selector = Class.create();
Finder.Selector.prototype = {
	initialize: function(element, options) {
		this.element = $(element);
		this.options = options || {};

		this.links = this.element.getElementsBySelector('a[name]');
		
		this.observe();
	},
	
	select: function(link) {
		link = this.links[typeof (link || this.links[0]) == 'string' ? $A(this.links).pluck('name').indexOf(link) : this.links.indexOf(link)] || this.links[0];
		$A(this.links).invoke('removeClassName', 'selected');
		$(link).addClassName('selected');
		(this.options.onSelect || Prototype.emptyFunction)($(link).name);
	},
	
	observe: function() {
		this.onClick = this.onClick.bindAsEventListener(this);
		$A(this.links).invoke('observe', 'click', this.onClick);
	},
	
	onClick: function(e) {
		Event.stop(e);
		if (!Event.element(e).hasClassName('selected')) this.select(Event.element(e));
	}
}


// basic element

Finder.Element = Class.create();
Finder.Element.prototype = {
    is_element: true,
    
    initialize: function(element, options) {
        this.element = $(element);
        this.options = options || {};
        this.childElements = [];
        this.parentElement = undefined;
        this.lock_counter = 0;
        this.is_ready = true;
        this.transition = undefined;
    },
    
    show: function() {
        this.element.show();
    },
    
    hide: function() {
        this.element.hide();
    },
    
    visible: function() {
        return this.element.visible();
    },
    
    push: function(element) {
        if (element.is_element) {
            if ($A(this.childElements).indexOf(element) < 0)
                this.childElements.push(element);
            element.parentElement = this;
        }
        return this;
    },
    
    busy: function(lock_self) {
        if (lock_self) {
            this.lock_counter++;
            (this._lock || Prototype.emptyFunction).apply(this);
        }
        if (this.parentElement) this.parentElement.busy(true);
    },
    
    free: function(unlock_self) {
        if (unlock_self) {
            this.lock_counter -= this.lock_counter > 0 ? 1 : 0;
            (this._unlock || Prototype.emptyFunction).apply(this);
        }
        if (this.parentElement) this.parentElement.free(true);
    },
    
    lock: function() {
        (this._lock || Prototype.emptyFunction).apply(this);
        $A(this.childElements).invoke('lock');
    },
    
    unlock: function() {
        (this._unlock || Prototype.emptyFunction).apply(this);
    },
    
    ready: function() {
        return this.is_ready && $A(this.childElements).invoke('ready').indexOf(false) < 0;
    },
    
    activate: function() {
        this.transition = 'activate';
        this.activate_before();
        this.activate_in();
    },
    
    activate_before: function() {
        this.lock();
        this.busy();
        this.show();
    },
    
    activate_in: function() {
        this.activate_after();
    },
    
    activate_after: function(without_chain) {
        this.transition = undefined;
        this.unlock();
        this.free();
        if (!without_chain)
            $A($(this.childElements)).invoke('activate');
    },
    
    deactivate: function() {
        this.deactivate_before();
        this.deactivate_in();
    },
    
    deactivate_before: function() {
        this.lock();
        this.hide();
    },
    
    deactivate_in: function() {
        this.deactivate_after.apply(this, arguments);
    },
    
    deactivate_after: function() {
        $A(this.childElements).invoke('deactivate');
    },
    
    update: function() {
        this.transition = 'update';
        this.update_before();
        this.update_in();
    },
    
    update_before: function() {
        this.busy();
        this.lock();
    },
    
    update_in: function() {
        this.update_after.apply(this, arguments);
    },
    
    update_after: function(without_chain) {
        this.transition = undefined;
        this.unlock();
        this.free();
        if (!without_chain)
            $A(this.childElements).invoke('update');
    }
};


// control element

Finder.ControlElement = Class.create();
Object.extend(Finder.ControlElement.prototype, Finder.Element.prototype);
Object.extend(Finder.ControlElement.prototype, {
    is_control_element: true,
    
    initialize: function() {
        Finder.Element.prototype.initialize.apply(this, arguments);
        this.controlElement = this.element.getElementsBySelector('input,select,textarea').shift();
        this.name = this.options.name || this.controlElement.name;
    },
    
    _lock: function() {
        this.controlElement.disable();
    },
    
    _unlock: function() {
        this.controlElement.enable();
    },
    
    getName: function() {
        return this.name;
    },
    
    getValue: function() {
        return this.value || $F(this.controlElement);
    },
    
    getParameters: function() {
        result = {};
        result[this.getName()] = this.getValue();
        return result;
    }
});


// chain

Finder.Chain = Class.create();
Object.extend(Finder.Chain.prototype, Finder.ControlElement.prototype);
Object.extend(Finder.Chain.prototype, {
    initialize: function() {
        Finder.ControlElement.prototype.initialize.apply(this, arguments);
        this.onClick = this.onClick.bindAsEventListener(this);
        this.getChildParameters = this.getChildParameters.bind(this);
        this.loaded = false;
    },
    
    activate_in: function() {
        this.controlElement.observe('click', this.onClick);
        Finder.ControlElement.prototype.activate_in.apply(this, arguments);
    },
    
    deactivate_in: function() {
        this.controlElement.stopObserving('click', this.onClick);
        Finder.ControlElement.prototype.deactivate_in.apply(this, arguments);
    },

    _unlock: function() {      	
        if (this.ready()) {        	
            Finder.ControlElement.prototype._unlock.apply(this, arguments);
            if (!this.loaded) {
                (this.options.onLoad || Prototype.emptyFunction)(this.collect());
                this.loaded = true;
            }
        }
    },
    
    collect: function() {
        return this.collectParameters({}, this.childElements);
    },
    
    collectParameters: function(container, children) {
        return $A(children).inject(container, this.getChildParameters);
    },
    
    getChildParameters: function(container, child) {
        if (child.is_control_element && child.visible()) {
            Object.extend(container, child.getParameters());
            Object.extend(container, this.collectParameters(container, $A(child.childElements)));
        }
        return container;
    },
    
    onClick: function(e) {
        (this.options.onClick || Prototype.emptyFunction)(this.collect());
    }
});


// select element

Finder.SelectElement = Class.create();
Object.extend(Finder.SelectElement.prototype, Finder.ControlElement.prototype);
Object.extend(Finder.SelectElement.prototype, {
    initialize: function() {
        Finder.ControlElement.prototype.initialize.apply(this, arguments);
        this.data = this.options.data || [];
        this.optionValueName = this.options.optionValueName || 'id';
        this.optionTextName = this.options.optionTextName || 'title';
        this.value = this.options.value;
        this.onChange = this.onChange.bindAsEventListener(this);
        this._buildOption = this._buildOption.bind(this);
        
        this.is_ready = false;
    },
    
    activate_in: function() {
        this.clear();
        this.build();
        this.controlElement.observe('change', this.onChange);
        Finder.ControlElement.prototype.activate_in.apply(this, arguments);
    },
    
    deactivate_in: function() {
        this.controlElement.stopObserving('change', this.onChange);
        this.clear();
        Finder.ControlElement.prototype.deactivate_in.apply(this, arguments);
    },
    
    update_in: function() {
        this.clear();
        this.build();
        Finder.ControlElement.prototype.update_in.apply(this, arguments);
    },
    
    _unlock: function() {
        if ($A(this.controlElement.childElements()).size() > 1)
            this.controlElement.enable();
    },
    
    clear: function() {
        $A(this.controlElement.childElements()).invoke('remove');
    },
    
    build: function() {
        this.is_ready = false;
        $A(this.data).each(this._buildOption);
        this.setValue(this.value);
        this.is_ready = $A(this.controlElement.childElements()).size() > 0;
    },
    
    _buildOption: function(option) {
        this.controlElement.appendChild(Builder.node('option', {value: option[this.optionValueName]}, option[this.optionTextName]));
    },
    
    setValue: function(value) {
        this.controlElement.selectedIndex = this.controlElement.childElements().pluck('value').indexOf(value || this.value);
        if (this.controlElement.selectedIndex < 0) this.controlElement.selectedIndex = 0;
        this.value = $F(this.controlElement);
    },
    
    onChange: function(e) {
        this.setValue($F(this.controlElement));
        this.update_after();
        (this.options.onChange || Prototype.emptyFunction)(this.value);
    }
});


// date element

Finder.DateElement = Class.create();
Object.extend(Finder.DateElement.prototype, Finder.ControlElement.prototype);
Object.extend(Finder.DateElement.prototype, {
    initialize: function() {
        Finder.ControlElement.prototype.initialize.apply(this, arguments);
        this.value = Finder.Date.stringDBToDate(this.options.value);
        this.onChange = this.onChange.bindAsEventListener(this);
        if (this.options.anchor)
        	MxCalendar.create(this.options.anchor, this.controlElement, this);        
    },
    
    activate_in: function() {
        this.clear();
        this.build();
        this.controlElement.observe('change', this.onChange);
        Finder.ControlElement.prototype.activate_in.apply(this, arguments);
    },
    
    deactivate_in: function() {
        this.controlElement.stopObserving('change', this.onChange);
        this.clear();
        Finder.ControlElement.prototype.deactivate_in.apply(this, arguments);
    },
    
    update_in: function() {
        this.clear();
        this.build();
        Finder.ControlElement.prototype.update_in.apply(this, arguments);
    },
    
    build: function() {
        this.setValue();
        if (this.parentElement.getValue() == 'history')
            this.show();
        else
            this.hide();
    },
    
    clear: function() {
        this.controlElement.value = '';
    },
    
    setValue: function(value) {
        if (value) this.value = Finder.Date.stringToDate(value);
        this.controlElement.value = Finder.Date.dateToString(this.value);
    },
    
    getValue: function() {
        return Finder.Date.dateToStringDB(this.value);
    },
    
    onChange: function(e) {
        this.setValue($F(this.controlElement));
        this.update_after();
    },
    
    disable: function() {
    	this.controlElement.disable();
    	if (this.options.anchor) {    		
    		//$(this.options.anchor).setOpacity(0);
    		$(this.options.anchor).hide();
    	}
    },
    
    enable: function() {
    	this.controlElement.enable();
    	if (this.options.anchor) {    		
    		//$(this.options.anchor).setOpacity(1);
    		$(this.options.anchor).show();
    	}
    }
});


// instrument info element

Finder.InstrumentInfoElement = Class.create();
Object.extend(Finder.InstrumentInfoElement.prototype, Finder.Element.prototype);
Object.extend(Finder.InstrumentInfoElement.prototype, {
    initialize: function() {
        Finder.Element.prototype.initialize.apply(this, arguments);
        this.links = this.element.getElementsBySelector('a[name]');
        this.buildLink = this.buildLink.bind(this);
        this.onClick = this.onClick.bindAsEventListener(this);
    },
    
    activate_in: function() {
        this.clear();                
        if (!$H(this.parentElement.data).size()) {this.free(); return};
        this.build();
        $A(this.links).invoke('observe', 'click', this.onClick);
        Finder.Element.prototype.activate_in.apply(this, arguments);
    },
    
    deactivate_in: function() {
        $A(this.links).invoke('stopObserving', 'click', this.onClick);
        Finder.ControlElement.prototype.deactivate_in.apply(this, arguments);
    },

    update_in: function() {
        this.clear();
        if (!$H(this.parentElement.data).size()) {this.free(); return};
        this.build();
        $A(this.links).invoke('stopObserving', 'click', this.onClick);
        $A(this.links).invoke('observe', 'click', this.onClick);
        Finder.Element.prototype.update_in.apply(this, arguments);
    },
    
    buildLink: function(link) {
    
        if (!$(link).hasClassName('ever')) $(link).removeClassName('disabled');
        
        $(link).show(); $(link).up().show();
        
        link.innerHTML = this.parentElement.data[link.name] || '&mdash';
        
        if (!this.parentElement.data[link.name]) {
            link.addClassName('disabled');
            if(!link.hasClassName('ever')) link.up().hide();
            link.hide();
        }
    },
    
    build: function() {
        $A(this.links).each(this.buildLink);
        this.selectLink();
        this.show();
    },
    
    selectLink: function() {
        if(this.links){
            $A(this.links).invoke('removeClassName', 'selected');
            link = $A(this.links).find(function(link) {return link.innerHTML == $F(this.parentElement.controlElement);}.bind(this));
            if(link)
                link.addClassName('selected');
        }
    },
    
    clear: function() {
        this.hide();
    },
    
    onClick: function(e) {
        Event.stop(e);
        link = Event.element(e);
        if (link.hasClassName('ever') || link.hasClassName('disabled') || link.hasClassName('selected')) return;
        this.parentElement.controlElement.value = link.innerHTML.unescapeHTML();
        this.selectLink();
    }
    
});



// basic ajax element
Finder.AjaxElement = Class.create();
Finder.AjaxElement.prototype = {
    initialize: function() {
        if (this.element)
            this.indicator = this.element.getElementsBySelector('.indicator').shift();
        if(this.options) this.onLoad = this.options.onLoad;
    },
    
    showIndicator: function() {
        if (this.indicator) this.indicator.show();
    },
    
    hideIndicator: function() {
        if (this.indicator) this.indicator.hide();
    }
}


// ajax select element

Finder.AjaxSelectElement = Class.create();
Object.extend(Finder.AjaxSelectElement.prototype, Finder.SelectElement.prototype);
Object.extend(Finder.AjaxSelectElement.prototype, Finder.AjaxElement.prototype);
Object.extend(Finder.AjaxSelectElement.prototype, {
    initialize: function() {
        Finder.SelectElement.prototype.initialize.apply(this, arguments);
        Finder.AjaxElement.prototype.initialize.apply(this, arguments);
        this.onSuccess = this.onSuccess.bind(this);
        this.onFailure = this.onFailure.bind(this);
        this.hideIndicator();
    },
    
    activate_in: function() {
        if ($A(this.data).size()) Finder.SelectElement.prototype.activate_in.apply(this, arguments);
        else this.update_in();
    },
    
    update_in: function() {
        this.clear();
        this.load();
    },
    
    load: function() {
        if (this.parentElement.is_control_element && !this.parentElement.getValue()) return this.delegate(true);
        
        this.showIndicator();
        
        new Ajax.Request(this.options.url, {
            method: 'get',
            parameters: this.parentElement.is_control_element ? this.parentElement.getParameters() : {},
            onSuccess: this.onSuccess,
            onFailure: this.onFailure
        });
    },
    
    onSuccess: function(transport) {
        this.hideIndicator();
        this.data = [];
        try {this.data = transport.responseText.evalJSON();} catch(e) {}
        if (!$A(this.data).size()) alert('Данные не найдены');
        this.delegate(!$A(this.data).size());
        (this.options.onChange || Prototype.emptyFunction)(this.value);
    },
    
    onFailure: function(transport) {
        this.hideIndicator();
        alert (transport.responseText);
        alert('failure');
        this.delegate();
        this.lock();
    },
    
    delegate: function() {
        switch(this.transition) {
            case 'activate':
                Finder.SelectElement.prototype.activate_in.apply(this, arguments);
                break;
            case 'update':
                Finder.SelectElement.prototype.update_in.apply(this, arguments);
                break;
            default:
                alert('Неизвестное состояние обновления "' + this.transition + '"!');
                throw 'Неизвестное состояние обновления "' + this.transition + '"!';
        }
    }
});


// ajax autocomplete element

Finder.AjaxAutocompleteElement = Class.create();
Object.extend(Finder.AjaxAutocompleteElement.prototype, Finder.ControlElement.prototype);
Object.extend(Finder.AjaxAutocompleteElement.prototype, Finder.AjaxElement.prototype);
Object.extend(Finder.AjaxAutocompleteElement.prototype, {
    initialize: function() {
        Finder.ControlElement.prototype.initialize.apply(this, arguments);
        Finder.AjaxElement.prototype.initialize.apply(this, arguments);
        this.is_ready = false;

        //this.autocompleteListElement = this.element.getElementsBySelector('.autocomplete-data').shift();
        this.autocompleteListElement = $('autocomplete-data-element');
        if (!this.autocompleteListElement) {
            this.autocompleteListElement = document.createElement('div');
            this.autocompleteListElement.id = 'autocomplete-data-element';
            ($('left-content') || $('page')).appendChild(this.autocompleteListElement);
        }
        this.autocompleteListElement = $(this.autocompleteListElement);
        this.autocompleteListElement.addClassName('autocomplete-data');
        this.autocompleteListElement.hide();
        this.hideIndicator();
        
        this.updateElement = this.updateElement.bind(this);

        this.start();
    },
    
    activate_in: function() {
        this.clear();
        this.build();
        Finder.ControlElement.prototype.activate_in.apply(this, arguments);
    },
    
    deactivate_in: function() {
        this.clear();
        Finder.ControlElement.prototype.deactivate_in.apply(this, arguments);
    },
    
    build: function() {
        this.controlElement.value = this.value || '';
    },
    
    clear: function() {
        this.controlElement.value = '';
    },

    start: function() {
        if(this.options.securityInfo && this.options.securityInfo.secid){
            this.controlElement.value = this.value = this.options.securityInfo.secid.unescapeHTML();
            this.data=$H(this.options.securityInfo);
            this.is_ready = true;
            this.update_after();
        }
        new Ajax.Autocompleter(this.controlElement, this.autocompleteListElement, this.options.url, {
                paramName: this.options.paramName,
                minChars: this.options.minChars || 3,
                indicator: this.indicator,
                updateElement: this.updateElement,
                method: 'get'
        });
    },
    
    setValue: function(li) {
        this.controlElement.value = this.value = li.id.unescapeHTML();
    },
    
    updateElement: function(li) {
        this.setValue(li);
        this.is_ready = true;
        this.update_after();
    }
});


// instrument autocomplete element

Finder.InstrumentAjaxAutocompleteElement = Class.create();
Object.extend(Finder.InstrumentAjaxAutocompleteElement.prototype, Finder.AjaxAutocompleteElement.prototype);
Object.extend(Finder.InstrumentAjaxAutocompleteElement.prototype, {
    setValue: function(li) {
        this.value = li.id.unescapeHTML();
        result = $H(this.data).values().find(function(value) { return value && new String(value).toLowerCase().startsWith($F(this.controlElement).toLowerCase());}.bind(this));
        this.controlElement.value = (result || this.value).unescapeHTML();
    },
    
    updateElement: function(li) {
        try { this.data = li.getElementsBySelector('.data').shift().innerHTML.evalJSON(); } catch(e) { this.data = {}; }
        if (!$H(this.data).size())
            alert('Нет данных по инструменту');
        else{
            Finder.AjaxAutocompleteElement.prototype.updateElement.apply(this, arguments);
        }
    }
});

