Element.Events.hashchange = {
    onAdd: function () {
        var hash = location.hash;

        var hashchange = function () {
            if (hash == location.hash) return;
            else hash = location.hash;

            var value = (hash.indexOf('#') == 0 ? hash.substr(1) : hash);
            window.fireEvent('hashchange', value);
            document.fireEvent('hashchange', value);
        };

        if ("onhashchange" in window) {
            window.onhashchange = hashchange;
        }
        else {
            hashchange.periodical(50);
        }
    }
};

// Tour-klasse
Tour = new Class({

    Implements: [Options],

    options: {
        'container': null,
        'logs_limit': 10,
        'debug': false,
        'main': 'tour'
    },

    current: {
        
        tour : 0,
        step : 0,
        set     : {}
       
    },
    
    cleanups: [],

    // Initalize 
    initialize: function(options) {

        var these = this;

        these.setOptions(options);

        these.fragment = these.options.fragment;
        window.addEvent('hashchange', function(e) { these.parse() });
        these.parse();

    },
 
    // dispatch the url-fragment #!/tour/…/step/…/part/…
    parse: function() {

        var these = this;

        these.uri = new URI(document.location.href);

        var fragment = these.uri.get('fragment');

        if ( fragment === "") {
            fragment = these.fragment;
            these.fragment = undefined;
        }



        var splitted = fragment.split('/');

        if ( splitted[1] === 'tour' ) {

            // parse fragments into data
            these.tour = splitted[2];
            these.step = splitted[4];

            if ( these.tour != these.current.tour ) {

                

                var jsonRequest = new Request.JSON({url: '/tour/get_tour', 

                    onSuccess: function(data){
                       
                        these.current.tour = these.tour;
                        these.options.steps = data;
                        these.max = data.max;

                        var myKeyboardEvents = new Keyboard({
                                defaultEventType: 'keyup',
                                events: {
                                    'right': these.next.bind(these),
                                    'left':  these.prev.bind(these),
                                    'esc': these.end.bind(these),
                                    'n': these.next.bind(these),
                                    'p':  these.prev.bind(these),
                                    'e': these.end.bind(these),
                                    'r': these.play.bind(these)
                                }
                        });

                        myKeyboardEvents.activate();


                        these.dispatch();
                    }

                }).get({ tour_id: these.tour });

            
            } else {

                these.dispatch();
            }

        } else {


        }
    },

    dispatch: function() {

        var these = this;

        if ( these.step  != these.current.step ) {
            
            these.run(these.step) ;
            these.current.step = these.step;
        }

    },


    set_mask : function(el ) {

        var these = this;

        $$('.tour-dimmer').destroy();

        var coor = el.getCoordinates();

        var top_dimmer      = new Element('div', { 'class': 'tour-dimmer', id: 'tour-dimmer-wrapper-top' });
        var bottom_dimmer   = new Element('div', { 'class': 'tour-dimmer', id: 'tour-dimmer-wrapper-bottom' });
        var left_dimmer     = new Element('div', { 'class': 'tour-dimmer', id: 'tour-dimmer-wrapper-lef' });
        var right_dimmer    = new Element('div', { 'class': 'tour-dimmer', id: 'tour-dimmer-wrapper-right' });
        
        top_dimmer.setStyle('top', 0);
        top_dimmer.setStyle('left',0);
        top_dimmer.setStyle('right', 0 );
        top_dimmer.setStyle('height', coor['top'] );
        top_dimmer.inject(document.body);

        left_dimmer.setStyle('top', coor['top']);
        left_dimmer.setStyle('left',0);
        left_dimmer.setStyle('width', coor['left'] );
        left_dimmer.setStyle('right', coor['width'] + coor['right']);
        left_dimmer.setStyle('height', coor['height'] );
        left_dimmer.inject(document.body);

        right_dimmer.setStyle('top', coor['top']);
        right_dimmer.setStyle('left', coor['left'] + coor['width']);
        right_dimmer.setStyle('right', 0);
        right_dimmer.setStyle('height', coor['height'] );
        right_dimmer.inject(document.body);

        bottom_dimmer.setStyle('top', coor['top'] + coor['height']);
        bottom_dimmer.setStyle('left',0);
        bottom_dimmer.setStyle('right', 0);
        bottom_dimmer.setStyle('bottom', 0 );
        bottom_dimmer.inject(document.body);
       
        $$('.tour-dimmer').addEvent('click', function()  { these.end() });

    },


    run: function(step) {

        var these = this;
    
        var steps = these.options.steps;
        

        var set = {};

        var prev = undefined;

        if (these.current.set !== undefined ) {
            prev = these.current.set.url;
        }

        if ( steps !== undefined ) {

            set['action']       = steps[step + '_action'];
            set['duration']     = steps[step + '_duration'];
            set['parameter1']   = steps[step + '_parameter1'];
            set['parameter2']   = steps[step + '_parameter2'];
            set['parameter3']   = steps[step + '_parameter3'];
            set['parameter4']   = steps[step + '_parameter4'];
            set['xpath']        = steps[step + '_xpath'];
            set['url']          = steps[step + '_url'];
            set['step']        = step;

            if ( set.action ) {
                
               these.current.set = set;
               var current_uri = these.uri ;

               if ( prev == set['url'] || prev === undefined) {

                    these["action_" +set.action].apply(these,[set]);

               } else {

                    var fragment = "!/tour/"+these.tour+"/step/"+step ;
                    var load_uri    = new URI( these.options.base + set.url) ;
                    load_uri.setData( { 'fragment': fragment }, true);
                    these.uri = load_uri;

                    these.uri.go(); 

                }
            }
        }
    },
     
    // next dispatcher
    runnext: function() {

        var these = this;

        var set = these.current.set;

        these.cleanup();

        if ( these.step < these.max ) {

            these.step = + these.step + 1;
            these.run(these.step);

        }

    },
    
    cleanup: function() {

        var these = this;
        
        while ( these.cleanups.length ) {
            
            var item = these.cleanups.pop();
            item();
        }
    },

    // next dispatcher
    runprev: function() {

        var these = this;
        
        var set = these.current.set;

        these.cleanup();

        if ( these.step > 1 ) {

            these.step = +these.step - 1;
            these.run(these.step);
        }

    },


    // Trigger next
    next: function() {

        var these = this;

        if ( these.step == these.max ) {

            these.end();

        } else {

            these.runnext();
        }

    },

    // Trigger previous

    prev: function() {

        var these = this;
        
        these.runprev( );

   },

    // stop tour
    stop: function() {

        var these = this;
    },

    play: function() {

      
        var these = this;
        these.runnext();
    },

    // end/hide tour 
    end: function() {

        var these = this;

        these.cleanup();

        these.uri.set('fragment','');

        window.location.href="#";

        these.current = {};

        $$('.tour-dimmer').destroy();
        these.step = 0;
        these.options.steps = undefined;
    },

    restart: function() {

        var these = this;

        these.cleanup();
        these.step = 0;
        these.runnext();

    },


    action_light: function(set) {

        var these = this;



        these.runnext();
    },

    cmp_uri: function(a,b) {

        var a_directory = a.get('directory');
        var a_file      = a.get('file');
        var a_query     = a.get('query');
        var a_fragment =  a.get('fragment');

        var a_string =  a_directory + a_file + "?" + a_query; 

        var b_directory = b.get('directory');
        var b_file      = b.get('file');
        var b_query     = b.get('query');

        var b_string =  b_directory + b_file  + "?" + b_query;

        return ( a_string === b_string ) ;

    },

    
    // Load url
    action_load: function(set) {

        var these   = this;
   
        if ( set.parameter1 ) {
            these.box_title.set( 'html', set.parameter1 ) ;
        }

        if ( set.parameter2 ) {
            these.box_text.set( 'html', set.parameter2 ) ;
        }
        
    },

    // Highlight element
     action_box: function(set) {

        var these = this;

        var cb = function() {};


        var pos = new Element('div', { 'class': 'tour-highlight' });
        var pos_w = new Element('div', { 'class': 'tour-highlight-wrapper' }).inject(pos);
    

        var wisize = window.getSize();

    
        pos.setStyle('z-index',999999);

        pos.setStyle('left', wisize.x / 2 - 150 );
        pos.setStyle('top', 100);
        pos.setStyle('position', 'absolute');

        window.scrollTo(0,0 ) ;

        var pos_title  = new Element('h3').inject(pos_w);
        var pos_text   = new Element('p').inject(pos_w);
        var pos_close  = new Element('a', {'class': 'tour-close' }).inject(pos_w);
        var pos_state  = new Element('span', {'class': 'tour-state' }).inject(pos_w);
        var pos_bottom = new Element('p').inject(pos_w);
        var pos_link   = new Element('a', { 'class': 'tour-forward' }).inject(pos_bottom);

        pos_title.set('html',set.parameter1);
        pos_text.set('html',set.parameter2);
        pos_close.set('text', loc('Abbrechen'));
        pos_link.set('text', set.parameter3);
        
        pos_state.set('text', these.step + "/" + these.max );

        pos_close.addEvent('click', function() { these.end() });
                            
        if ( these.step == these.max ) {

            pos_link.addEvent('click', function() { these.restart() });

        }  else  {

            pos_link.addEvent('click', function() { these.next() } );
                    
        }
        
        pos.inject(document.body);

        these.set_mask(pos);

        these.cleanups.push( function() { pos.destroy(); });


    },



    // Highlight elementM
     action_highlight: function(set) {

        var these = this;
        var xpath = set.xpath;
        var elements = $$(xpath);

        var cb = function() {};

        if ( elements.length > 0) {

            var pos = new Element('div', { 'class': 'tour-highlight' });

            var pos_w = new Element('div', { 'class': 'tour-highlight-wrapper' }).inject(pos);
            
            var el = elements[0]; 
        

            

            // statische Elemente, relativ positionren
            if (el.getStyle('position') == 'static' ) {
                el.setStyle('position','relative');
            } 

            var wisize = window.getSize();
            var elsize = el.getSize();
            var elpos  = el.getPosition();
            var elbg   = el.getStyle('background-color');

            var xpos = elpos.x  - 900 ;
            var ypos = elpos.y  - 950;

            these.set_mask(el);

            window.scrollTo( elpos.x - these.offset_x - 10, elpos.y - 10 - these.offset_y ) ;

            var space_right = wisize.x - (elpos.x + elsize.x);
            var space_left  = elpos.x;
            var space_top   = elpos.y; 

            var position = 'topRight';
            var edge     = 'topLeft';

            //console.log("Space top   " + space_top ) ;
            //console.log("Space right " + space_right ) ;
            //console.log("Space left   " + space_left ) ;

            if ( space_right > 300 ) {

                position = 'topRight';
                edge     = 'topLeft';
                pos.addClass('tour-highlight-marker-right');

           } else if ( space_top > 200 ) {

                position = 'topcenter';
                edge     = 'bottomcenter';
                pos.addClass('tour-highlight-marker-top');


            } else  if ( space_right <= 300 && space_left > 300 ) {

                position = "topLeft";
                edge     = "topRight";
                
                pos.addClass('tour-highlight-marker-left');

            } else {

                position = 'bottomLeft';
                edge     = 'topleft';
                pos.addClass('tour-highlight-marker-bottom');

            }

            var pos_title  = new Element('h3').inject(pos_w);
            var pos_text   = new Element('p').inject(pos_w);
            var pos_close  = new Element('a', {'class': 'tour-close' }).inject(pos_w);
            var pos_state  = new Element('span', {'class': 'tour-state' }).inject(pos_w);
            var pos_bottom = new Element('p').inject(pos_w);
            var pos_link   = new Element('a', { 'class': 'tour-forward' }).inject(pos_bottom);


            pos_title.set('html',set.parameter1);
            pos_text.set('html',set.parameter2);
            pos_close.set('text', loc('Abbrechen'));
            pos_link.set('text', set.parameter3);
            pos_state.set('text', these.step + "/" + these.max );

            pos.inject(document.body);
            pos.position( { relativeTo: el, 'position': position, 'edge': edge });
 
            pos_close.addEvent('click', function() { these.end() });

            if ( these.step == these.max ) {
    
                pos_link.addEvent('click', function() { these.restart() });
    
            }  else  {

                pos_link.addEvent('click', function() { these.next() } );
                      
            }
            
 
            these.cleanups.push( function() {  pos.destroy(); });
        
        }
    
    },

    // Move spot to element
    action_moveto: function(set) {


    }

});

// Tour-Manager-klasse
TourManager = new Class({

    Implements: [Options],

    options: {
        debug: 1
    },

    // Initalize 
    initialize: function(options) {

        var these = this;

        these.setOptions(options);


        $$('.manage-form').addEvent('submit', function(e) {
            e.stop();


            these.save();
        });

        these.options.addstep.addEvent('click', function(e) {


            var event = new Event(e);

            event.stop();

            these.add_step(these.options.addstep);

        });


        $$('.manage-item-list').addEvent('click:relay(.manage-item-toolbar-up)',     function(e,target) { these.up_step(target.getParent('li')) } );
        $$('.manage-item-list').addEvent('click:relay(.manage-item-toolbar-down)',   function(e,target) { these.down_step(target.getParent('li')) } );
        $$('.manage-item-list').addEvent('click:relay(.manage-item-toolbar-add)',    function(e,target) { these.add_step(target.getParent('li')) } );
        $$('.manage-item-list').addEvent('click:relay(.manage-item-toolbar-delete)', function(e,target) { these.delete_step(target.getParent('li')) } );

    },

    // Setze die Sortierung neu 
    setsorting: function(el,sorting) {
       el.getElements('input[name=sorting]').set('value',sorting);
       el.getElements('.manage-item-sorting').set('text',sorting);
     },

    // setze die Sortierung neu
    resorting: function() {

        var these = this;
            
        var sortx = 1;
        $$('.manage-item-list li').each( function(el) { these.setsorting(el, sortx++) });

    },

    add_step: function(el) {

        var these = this;

        var selection = new Element('ul', { 'class': 'manage-item-add-selection' });

        var list = [ { name:  "Info-Box", code: 'box' }, { code : 'highlight', name: 'Hervorheben' } ];
        
        var title = new Element('li', { 'text': loc('Funktion'), 'class': 'title' }).inject(selection);

        list.each( function(ty) {

            var typ = new Element('li', { 'text': ty.name }).inject(selection);

            typ.addEvent('click',function(e) {

                selection.fade('out');
                these.add_step_do(el, ty.code ) ;
            });
            

        });

        selection.inject(document.body);
        selection.position( { 'relativeTo': (el.get('tag') === 'li' ? el.getElement('.manage-item-toolbar') : el ) , position: 'bottomRight',  edge: 'upperRight'});

    },

    add_step_do: function(el,code) {

        var these = this;

        var myHTMLRequest = new Request.HTML({url: these.options.newelement,
        
            onSuccess: function(responseText){
               
                var newelement = responseText[0];

                if ( el !== undefined && el.get('tag') === 'li' ) {

                    newelement.inject( el,'after' );             

                } else {

                    newelement.inject( $$('.manage-item-list')[0] );

                }
                these.resorting();
            }
        
        }).get({'action': code });


    },


    delete_step: function(el) {

        var these = this;
        
        el.destroy();
 
   
        these.resorting();
    },

    up_step: function(el) {
   
        var these = this;
 
   
        var prev = el.getPrevious('li');

        if ( prev ) {
            el.inject(prev,'before');
        }
 
        these.resorting();
     },

    down_step: function(el) {

         var these = this;
 
      
        var next = el.getNext('li');

        if ( next !== undefined ) {
            el.inject(next,'after');
        }

        these.resorting();
  

    },

    save: function() {

        var these = this;

        // Resort
        these.resorting();
        
        var fe = $$('.manage-form')[0];

        var meta_title = fe.getElement('input[name=title]').get('value');
         
        var data = {};

        data['title'] = meta_title;

        data['steps'] = [];

        $$('.manage-item-list li').each( function(el) {

            var el_duration    = el.getElement('input[name=duration]');
            var el_sorting    = el.getElement('input[name=sorting]');
            var el_parameter1 = el.getElement('*[name=parameter1]');
            var el_parameter2 = el.getElement('*[name=parameter2]');
            var el_parameter3 = el.getElement('*[name=parameter3]');
            var el_parameter4 = el.getElement('*[name=parameter4]');
            var el_url        = el.getElement('*[name=url]');
            var el_xpath      = el.getElement('input[name=xpath]');
            var el_action     = el.getElement('input[name=action]');
            var el_tour_step  = el.getElement('input[name=tour_step]');



            data['steps'].push( {

                duration:   ( el_duration   ? el_duration.get('value') : '' ),
                sorting:    ( el_sorting    ? el_sorting.get('value') : '' ),
                parameter1: ( el_parameter1 ? el_parameter1.value : '' ),
                parameter2: ( el_parameter2 ? el_parameter2.value : '' ),
                parameter3: ( el_parameter3 ? el_parameter3.value : '' ),
                parameter4: ( el_parameter4 ? el_parameter4.value : '' ),
                url:        ( el_url        ? el_url.get('value') : '' ),
                xpath:      ( el_xpath      ? el_xpath.get('value') : '' ),
                action:     ( el_action     ? el_action.get('value') : '' ),
                tour_step_id: ( el_tour_step     ? el_tour_step.get('value') : '' )


            });
            
        
        });

        var jdata = JSON.encode(data);

        var request = new Request( 
            { 
                url: these.options.update, 
            
                onSuccess: function() {

                    window.scrollTo(0,0);
                }
            }
        );

        request.post( { data: jdata });
    }

});

