// JavaScript Document ess.search.js
// Author Marko Stutz
// Live Search for e-special-shop.de
// Version: 1.0.0.1

moduls.push('<br>Modul: LiveSearch');

ess.ac.Base = new Class({
    Implements: [Events, Options],
    options: {
        container        : document.body,
        indicator        : null,
        paramName        : null,
        tokens           : [],
        frequency        : 0.4,
        minChars         : 2,
        minNotFoundChars : 5,
        defaultParamsFormId: null
    },
    
    initialize: function(input, options){
        this.input     = $(input);
        this.containerIsVisible = false;
        this.hasFocus    = false;
        this.changed     = false;
        this.active      = false;
        this.index       = 0;
        this.entrys      = [];
        this.entryCount  = 0;
        this.oldInputValue = this.input.value;
        this.changedSite = false;
        this.showHelp    = false;
        this.observer    = null;
        this.observerOnBlur = null;
        this.observerRequestId = 0;
        this.observerNotFound = null;
        
        this.site = -1;
        this.site1 = 0;
        this.maxsites1 = 0;
        
        this.iDebug = 0;
        
        this.setOptions(options);
        this.options.paramName    = this.options.paramName || this.input.name;
        
        this.init();

        this.moveBox = new ess.Effects.MoveBox(this.moveContainer);
        
        this.input.addEvents({'keydown': this.onKeyPress.bind(this)});//'blur': this.onBlur.bind(this),
        
        this.oArticle = null;
    },
    
    init: function(){
        this.options.container = this.options.container || document.body;
        this.wrapper = new Element('div', {id: 'ac','class':'acWrapper'}).injectInside(this.options.container).setStyle('visibility','hidden');
        this.iframe = new Element('iframe').setProperties({
			'id': 'acIframe', 'name': 'acIframe', 'src': 'javascript:void(0);', 'frameborder': 1, 'scrolling': 'no'
		}).setStyles({
			'position': 'absolute', 'top': -20, 'left': -20, 'width': '115%', 'height': '115%', 'filter': 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)', 'opacity': 0
		}).injectInside(this.wrapper);
		this.container = new Element('div', {'class':'acContainer'}).injectInside(this.wrapper);
		// debug
		this.ctlDebug = new Element('div',{'class':'acDebug'}).injectInside(this.container);
		// controlscontainer top
		this.ctlContainerTop = new Element('div',{'class':'acControlsContainer acControlsContainerTop'}).injectInside(this.container);
		this.closeButton = new Element('div',{'class':'acButtons acClose'}).injectInside(this.ctlContainerTop).addEvent('click', this.close.bind(this));
		this.helpButton = new Element('div',{'class':'acButtons acHelp'}).injectInside(this.ctlContainerTop).addEvent('click', this.onClickHelp.bind(this)).setStyle('visibility','hidden');
		this.ctlContainerTop.adopt( new Element('div', {'class': 'acContentTitle'}).set('text','Optionen der Live-Suche'), new Element('div', {'class': 'clear'}) );
		this.ctlOptions = new Element('div',{'class':'acOptions'}).injectInside(this.ctlContainerTop);
		this.inputImage = new Element('input',{'type':'checkbox', 'name':'acviewimage', 'checked':'checked'}).addEvent('change', this.onChangeOptions.bind(this));
		this.ctlOptions.adopt( this.inputImage, new Element('label', {'for':'acviewimage'}).set('html','Bilder anzeigen&nbsp;&nbsp;&nbsp;') );
		this.inputArtnum = new Element('input',{'type':'checkbox', 'name':'acviewartnum'}).addEvent('change', this.onChangeOptions.bind(this));
		this.ctlOptions.adopt( this.inputArtnum, new Element('label', {'for':'acviewartnum'}).set('html','Hersteller Nr. anzeigen&nbsp;&nbsp;&nbsp;') );
		this.inputPrice = new Element('input',{'type':'checkbox', 'name':'acviewprice', 'checked':'checked'}).addEvent('change', this.onChangeOptions.bind(this));
		this.ctlOptions.adopt( this.inputPrice, new Element('label', {'for':'acviewprice'}).set('html','Preis anzeigen&nbsp;&nbsp;&nbsp;'), new Element('div', {'class': 'clear'}) );
		// top line
		this.container.adopt( new Element('div', {'class': 'acTopLine'}) );
		// content right
		this.contentRight = new Element('div',{'class':'acContentRight acHide'}).injectInside(this.container);
		// words
		this.ctlContainer4 = new Element('div').addClass('acControlsContainer').injectInside(this.contentRight);
		this.ctlContainer4.adopt( new Element('div', {'class': 'acContentTitle'}).set('html','verwandte Suchw&ouml;rter'), new Element('div', {'class': 'clear'}) );
		this.contentRight.adopt( new Element('div', {'class': 'acControlLine'}) );
		this.boxEntrys4 = new Element('div', {'class': 'acEntryContainer'}).injectInside(this.contentRight);
		
		// content left
		this.contentLeft = new Element('div',{'class':'acContentLeft acRightIsHide'}).injectInside(this.container);
		
		// article
		this.ctlContainer1 = new Element('div').addClass('acControlsContainer').injectInside(this.contentLeft);
		this.pgUpButton1 = new Element('div',{'class':'acButtons acPgUp'}).injectInside(this.ctlContainer1).addEvent('click', function(e){new Event(e).stop(); this.pageUp();}.bind(this));
		this.siteInfo1 = new Element('div', {id: 'ac_si1', 'class': 'acSiteInfo'}).appendText('Seite 1 von 1').injectInside(this.ctlContainer1);
		this.pgDownButton1 = new Element('div',{'class':'acButtons acPgDown'}).injectInside(this.ctlContainer1).addEvent('click', function(e){new Event(e).stop(); this.pageDown();}.bind(this));
		this.ctlTitle1 = new Element('div', {'class': 'acContentTitle'}).appendText('Produkte(0)').injectInside(this.ctlContainer1);
		this.ctlContainer1.adopt( new Element('div', {'class': 'clear'}) );
		this.contentLeft.adopt( new Element('div', {'class': 'acControlLine'}) );
		this.boxEntrys1 = new Element('div', {'class': 'acEntryContainer'}).injectInside(this.contentLeft);
		
		this.container.adopt( new Element('div', {'class': 'clear'}) );
		
		//spaeter in ess.Effects.MoveBox verschieben ???
		this.moveContainer = new Element('div').addClass('acMoveContainer').setStyles({'visibility':'hidden'}).injectInside(document.body);
		
		// entry start
		this.setStartEntry(this.boxEntrys1);
		this.pgUpButton1.fade('hide');
		this.pgDownButton1.fade('hide');
    },
    
    open: function(){
        if(this.wrapper.getStyle('visibility')=='hidden') this.wrapper.fade('show');
    },
    
    extOpen: function(){
        if(this.input.value.length < this.options.minChars){//this.getToken().length
            this.clearContents();
            this.setStartEntry(this.boxEntrys1);
            this.pgUpButton1.fade('hide');
            this.pgDownButton1.fade('hide');
            this.ctlTitle1.set('text','Produkte(0)');
            this.siteInfo1.set('text','Seite 1 von 1');
            this.entrys = [];
            this.entryCount = 0;
            this.index = 0;
        }
        this.open();
    },
    
    close: function(){
        if(this.observerOnBlur && (this.changedSite || this.showHelp)) {
            clearTimeout(this.observerOnBlur);
            return;
        }
        this.stopIndicator();
        if(this.wrapper.getStyle('visibility')!='hidden') this.wrapper.fade('hide');
        this.hasFocus = false;
        this.active = false;
        this.resultIsVisible = false;
    },
    
    showContentRight: function(){
        this.contentLeft.removeClass('acRightIsHide');
        this.contentRight.removeClass('acHide');
    },
    
    hideContentRight: function(){
        if(!this.contentLeft.hasClass('acRightIsHide')) this.contentLeft.addClass('acRightIsHide');
        if(!this.contentRight.hasClass('acHide')) this.contentRight.addClass('acHide');
    },
    
    onBlur: function(){
        this.observerOnBlur = setTimeout(this.close.bind(this), 200);
    },
    
    onKeyPress: function(e){
        if(this.active){
            switch(e.key) {
                case 'tab': return;
                case 'enter':
                    if(this.resultIsVisible && !this.changed) this.selectEntry();
                    e.stop();
                    return;
                case 'esc':
                    this.close();
                    this.active = false;
                    e.stop(); return;
                case '"':
                    this.pageDown();
                    e.stop();
                    return;
                case '!':
                    this.pageUp();
                    e.stop();
                    return;
                case 'left': case 'right': return;
                case 'up':
                    this.markPrevious();
                    this.render();
                    e.stop();
                    return;
                case 'down':
                    this.markNext();
                    this.render();
                    e.stop();
                    return;
            }
        }else{
            if(e.key == 'enter'){
                e.stop(); return;
            }
            if(e.key == 'tab' || (Browser.Engines.webkit && Event.keyCode == 0)) return;
        }
        this.changed = true;
        this.hasFocus = true;

        if(this.observer) clearTimeout(this.observer);
        this.observer = setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
    },
    
    onHover: function(e){
        var entry = $(e.target);
        if(!entry.hasClass('acEntry'))
            entry = entry.getParent('div.acEntry');
        var eIndex = this.getEntryIndex(entry);
        if(this.index != eIndex){
            this.index = eIndex;
            this.render();
        }
        e.stop();
    },
    
    onMouseOverImage: function(e){
        var entry = $(e.target);
        var src = entry.getProperty('srcimage');
        if(src && src.indexOf('nopic') == -1){
            var newImage = new Element('img', {src: src});
            this.moveContainer.grab(newImage);
            this.moveBox.show();
        }
    },
    
    onMouseOutImage: function(e){
        this.moveContainer.empty();
        this.moveBox.hide();
    },
    
    onClick: function(e){
        var entry = $(e.target);
        if(entry){
            //this.index = this.getEntryIndex(entry);
            this.selectEntry();
        }else{
            this.close();
        }
        e.stop();
    },
    
    onClickHelp: function(){
        if(essBase && essBase.objects.oHelpBoxSearch){
            this.showHelp = true;
            essBase.objects.oHelpBoxSearch.options.fncClose = function(){this.showHelp = false; this.input.focus();}.bind(this);
            essBase.objects.oHelpBoxSearch.open($('mb_searchhelp'));
        }
    },
    
    onChangeOptions: function(){
        if(this.input.value.length >= this.options.minChars){//this.getToken().length
            if(this.iDebug > 0){
                this.setSearchTime(true);
            }
            this.site = 1;
            this.getUpdatedChoices();
            this.resultIsVisible = false;
            this.oldInputValue = this.input.value;
        }
    },
    
    onObserverEvent: function(e){
        this.changed = false;
        this.tokenBounds = null;
        if(this.input.value.length >= this.options.minChars){//this.getToken().length
            this.open();
            if(this.iDebug > 0){
                this.setSearchTime(true);
            }
            this.site = 1;
            this.getUpdatedChoices();
            this.resultIsVisible = false;
        }else{
            this.active = false;
            this.close();
        }
        this.oldInputValue = this.input.value;
    },
    
    onObserverNotFoundEvent: function(){
        if(this.input.value.length >= this.options.minNotFoundChars){
            this.sendNotFound();
        }
    },
    
    startIndicator: function(){
        if(this.options.indicator) ess.Element.show(this.options.indicator);
    },
    
    stopIndicator: function(){
        if(this.options.indicator) ess.Element.hide(this.options.indicator);
    },
    
    setSearchTime: function(blStart){
        if(this.searchTimeStart || blStart){
            var zeit = new Date();
            var min = zeit.getMinutes();
            var sek = zeit.getSeconds();
            var msek = zeit.getMilliseconds();
            if(blStart){
                this.searchTimeStart = msek + (sek*1000) + (min*60000);
            }else{
                var searchEnd = msek + (sek*1000) + (min*60000);
                this.ctlDebug.appendText('Suchzeit(mit JS) -> '+((searchEnd-this.searchTimeStart)/1000)+' Sekunden.');
            }
        }else{
            this.ctlDebug.appendText('initialisiere JS-DebugModus.');
        }
    },
    
    clearContents: function(){
        this.boxEntrys1.set('text', '');
        this.boxEntrys4.set('text', '');
        this.ctlDebug.set('text', '');
        this.hideContentRight();
    },
    
    updateChoices2: function(responseTree, responseElements, responseHTML, responseJavaScript){
        if(this.observerNotFound) clearTimeout(this.observerNotFound);
        if(!this.changed && this.hasFocus) {
            this.clearContents();
            this.ctlDebug.adopt(responseTree);
            if(responseJavaScript){
                var oEntry = {'iCnt': 0, 'index': 0};
                this.entrys = [];
                eval(responseJavaScript);
                oEntry = this.insertArticle(oEntry);
                
                if(this.oWord && this.oWord.iCnt > 0){
                    this.showContentRight();
                    oEntry = this.insertWords(oEntry);
                }
                
                this.entryCount = oEntry.iCnt;
                this.stopIndicator();
                this.index = 0;
                this.render();
                this.changedSite = false;
                this.input.focus();
                if(this.iDebug > 0){
                    this.setSearchTime(false);
                }
            }else{
                this.stopIndicator();
            }
        }
    },
    
    insertArticle: function(oEntry){
        if(this.oArticle){
            this.ctlTitle1.set('text','Produkte ('+this.oArticle.iCnt+')');
            aArticle = this.oArticle.aArticle;
            oEntry.iCnt += aArticle.length;
            var index = oEntry.index
            if(aArticle.length > 0) {
                for (var i = 0; i < aArticle.length; i++) {
                    var oArt = this.oArticle.aArticle[i];
                    var elEntry = new Element('div', {id: oArt.id, 'class': 'acEntry', 'index': index, 'link': oArt.link})
                                        .injectInside(this.boxEntrys1)
                                        .addEvents({'mouseover': this.onHover.bindWithEvent(this),'click': this.onClick.bindWithEvent(this)});
                    if(oArt.icon != 'null'){
                        var elEntryIcon = new Element('div', {'class': 'acEntryDiv acIcon'}).setStyle('backgroundImage','url(' + oArt.icon + ')').injectInside(elEntry);
                        if(oArt.pic != 'null'){
                            elEntryIcon.setProperty('srcimage', oArt.pic).addEvents({'mouseover': this.onMouseOverImage.bindWithEvent(this), 'mouseout': this.onMouseOutImage.bindWithEvent(this)});
                        }
                    }
                    var elEntryTitle = new Element('div', {'class': 'acEntryDiv acTitle'}).set('html',oArt.title).injectInside(elEntry);
                    if(oArt.artnum != 'null'){
                        var elEntryArtnum = new Element('div', {'class': 'acArtnum'}).set('html', 'Hersteller-Nr.: ' + oArt.artnum).injectInside(elEntryTitle);
                    }
                    if(oArt.price != 'null'){
                        var elEntryPrice = new Element('div', {'class': 'acEntryDiv acPrice'}).injectInside(elEntry);
                        elEntryPrice.set('html', '<strong>'+oArt.price+' EUR</strong><div>incl. MwSt zzgl. Versand</div>');
                    }
                    elEntry.adopt( new Element('div', {'class': 'clear'}) );
                    this.entrys.push(elEntry);
                    this.boxEntrys1.adopt( new Element('div', {'class': 'acLine'}) );
                    index++;
                }
                oEntry.index = index;
            }else{
                this.setNoEntry(this.boxEntrys1);
            }
        }
        return oEntry;
    },
    
    insertWords: function(oEntry){
        if(this.oWord){
            aWord = this.oWord.aWord;
            oEntry.iCnt += aWord.length;
            var index = oEntry.index
            if(aWord.length > 0){
                ess.Element.show(this.ctlContainer4);
                for(var i = 0; i < aWord.length; i++){
                    var elEntry = new Element('div', {id: i, 'class': 'acEntry', 'index': index, 'translateword': aWord[i]}).injectInside(this.boxEntrys4)
                                        .addEvents({'mouseover': this.onHover.bindWithEvent(this),'click': this.onClick.bindWithEvent(this)});
                    var elEntryTitle = new Element('div', {'class': 'acEntryDiv acTitle'}).set('html',aWord[i]).injectInside(elEntry);
                    elEntry.adopt( new Element('div', {'class': 'clear'}) );
                    this.entrys.push(elEntry);
                    this.boxEntrys4.adopt( new Element('div', {'class': 'acLine'}) );
                    index++;
                }
                oEntry.index = index;
            }else{
                ess.Element.hide(this.ctlContainer4);
            }
        }
        return oEntry;
    },
    
    setNoEntry: function(boxEntry){
        if(boxEntry){
            boxEntry.set('html', '<div class="acNoEntry">Leider konnte kein Produkt gefunden werden.</div>');
        }
    },
    
    setStartEntry: function(boxEntry){
        if(boxEntry){
            boxEntry.set('html', '<div class="acStartEntry">Bitte geben Sie einen oder mehrere Suchbegriffe, getrennt durch Leerzeichen, ein.</div>');
        }
    },
    
    render: function(){
        if(this.entryCount > 0){
            this.entrys.each(function(entry){entry.removeClass('selected');});
            this.getCurrentEntry().addClass('selected'); 
            if(this.hasFocus){
                this.active = true;
                this.resultIsVisible = true;
            }
        }else{
            this.active = false;
            this.resultIsVisible = false;
        }
    },
    
    getEntryIndex: function(entry){
        var index = entry.getProperty('index');
        index = isNaN(index) ? 0 : index*1;
        return index;
    },
    
    getEntry: function(index){
        if(index < this.entrys.length){
            return this.entrys[index];
        }else{
            return this.entrys.length > 0 ? this.entrys[0] : null;
        }
    },
    
    getCurrentEntry: function(){
        return this.getEntry(this.index);
    },
    
    markPrevious: function(){
        if(this.index > 0) this.index--;
        else this.index = this.entryCount-1;
        this.getEntry(this.index).scrollIntoView(false);
    },
    
    markNext: function(){
        if(this.index < this.entryCount-1) this.index++;
        else this.index = 0;
        this.getEntry(this.index).scrollIntoView(false);
    },
    
    pageDown: function(){
        if(this.site > 1){
            this.site -= 1;
            this.changedSite = true;
            this.getUpdatedChoices();
        }
    },
    
    pageUp: function(){
        if(this.site < this.maxsites1){
            this.site += 1;
            this.changedSite = true;
            this.getUpdatedChoices();
        }
    },
    
    selectEntry: function(){
        var entry = this.getCurrentEntry();
        var entryProperties = entry.getProperties('link','translateword');
        if(entryProperties.translateword){
            this.input.value = entryProperties.translateword;
            this.changedSite = true;
            this.getUpdatedChoices();
        }else{
            this.active = false;
            window.location.href = entryProperties.link;
        }
    }
});


ess.ac.search = new Class({
    Extends: ess.ac.Base,
    initialize: function(input, req_url, options){
        this.parent(input, options);
        this.req_options = {
            url: req_url,
            encoding: 'ISO-8859-1',
            evalScripts: true,
            evalResponse: true,
            data: '',
            onSuccess: this.onComplete.bind(this),
            onFailure: function(){alert('Leider ist ein Fehler aufgetreten! Bitte benutzen Sie die Standardsuche.');}
        };
    },
    getUpdatedChoices: function(){
        if(this.iDebug > 0){
            this.setSearchTime(true);
        }
        this.startIndicator();
        var utf8Token = escape(this.input.value);//this.getToken());
        var entry = encodeURIComponent(this.options.paramName) + '=' + encodeURIComponent(utf8Token);
        this.req_options.data = entry;
        this.req_options.data += '&site='+this.site;
        this.observerRequestId += 1;
        this.req_options.data += '&requestid='+this.observerRequestId;
        if(this.inputImage && this.inputImage.checked){
            this.req_options.data += '&blimage=true';
        }
        if(this.inputArtnum && this.inputArtnum.checked){
            this.req_options.data += '&blartnum=true';
        }
        if(this.inputPrice && this.inputPrice.checked){
            this.req_options.data += '&blprice=true';
        }
        
        var myRequest = new Request.HTML(this.req_options);
        myRequest.send();
    },
    onComplete: function(responseTree, responseElements, responseHTML, responseJavaScript) {
        this.updateChoices2(responseTree, responseElements, responseHTML, responseJavaScript);
    },
    sendNotFound: function() {
        var utf8Token = escape(this.input.value);//this.getToken());
        var entry = encodeURIComponent(this.options.paramName) + '=' + encodeURIComponent(utf8Token);
    
        var req_options = {
            url: this.req_options.url,
            encoding: this.req_options.encoding,
            evalScripts: true,
            evalResponse: true,
            data: entry+'&notfound=true',
            onSuccess: this.onCompleteNotFound.bind(this)
        };
        
        var myRequest = new Request.HTML(req_options);
        myRequest.send();
    },
    onCompleteNotFound: function(responseTree, responseElements, responseHTML, responseJavaScript){
        this.ctlDebug.adopt(responseTree);
    }
});
