# VjsHelper

A powerful utility class for customizing Video.js player controls with ease. This helper provides a simple and flexible API for modifying existing controls and adding custom buttons to the Video.js player control bar.

## Installation

```bash
npm install vjs-helper
```

## Basic Usage

```javascript
import VjsHelper from 'vjs-helper';

const player = videojs('my-player');
const vjsHelper = new VjsHelper(player, {
    debug: true,
    strictMode: true
});
```

## Features

- Customize existing Video.js controls
- Add custom buttons with full control over appearance and behavior
- Position controls precisely in the control bar
- Apply custom styles and event handlers
- Manage button states and properties
- Reset customizations individually or all at once

## API Reference

### Constructor Options

```javascript
const helper = new VjsPlayer(player, {
    debug: true,      // Enable debug logging
    strictMode: true, // Strict validation of options
    show: true        // Default visibility for new buttons
});
```

### Customizing Existing Buttons

```javascript
// Basic customization
vjsHelper.customizeButton('PlayToggle', {
    show: true,
    iconHTML: '<i class="custom-icon">▶</i>',
    styles: {
        'root': {
            'background-color': 'red',
            'border-radius': '4px'
        }
    }
});

// Advanced customization with events and positioning
vjsHelper.customizeButton('FullscreenToggle', {
    iconHTML: '<i class="fas fa-expand"></i>',
    styles: {
        'root': {
            'background': 'transparent',
            'color': '#fff'
        },
        'i': {
            'font-size': '1.5em'
        }
    },
    events: {
        'mouseenter': function() {
            this.addClass('hover-state');
        },
        'mouseleave': function() {
            this.removeClass('hover-state');
        },
        'click': function() {
            console.log('Custom fullscreen click handler');
        }
    },
    position: {
        relativeTo: 'PlayToggle',
        index: 1
    }
});
```

### Adding Custom Buttons

```javascript
// Simple custom button
vjsHelper.addCustomButton({
    name: 'ShareButton',
    title: 'Share Video',
    iconHTML: '<i class="fas fa-share"></i>',
    events: {
        click: function() {
            console.log('Share button clicked');
        }
    }
});

// Advanced custom button with positioning and styles
vjsHelper.addCustomButton({
    name: 'QualitySelector',
    title: 'Video Quality',
    iconHTML: '<i class="fas fa-cog"></i>',
    styles: {
        'root': {
            'background': 'linear-gradient(to right, #4a90e2, #357abd)',
            'border-radius': '4px',
            'padding': '8px 12px'
        },
        'i': {
            'font-size': '16px',
            'margin-right': '5px'
        }
    },
    events: {
        click: function() {
            // Quality selection logic
        },
        mouseenter: function() {
            // Hover state handling
        }
    },
    position: {
        relativeTo: 'FullscreenToggle',
        index: -1
    }
});
```

### Position Controls

```javascript
// Absolute positioning
vjsHelper.customizeButton('VolumePanel', {
    position: {
        index: 2 // Places at index 2 in control bar
    }
});

// Relative positioning
vjsHelper.customizeButton('CurrentTimeDisplay', {
    position: {
        relativeTo: 'TimeDivider',
        index: -1 // Places before TimeDivider
    }
});
```

### Applying Custom Styles

```javascript
vjsHelper.customizeButton('PlayToggle', {
    styles: {
        'root': {
            'background-color': '#2196F3',
            'border-radius': '50%',
            'width': '40px',
            'height': '40px'
        },
        '.vjs-icon-placeholder': {
            'color': 'white',
            'font-size': '20px'
        },
        '.vjs-icon-placeholder:hover': {
            'color': '#E3F2FD'
        }
    }
});
```

### Event Handling

```javascript
vjsHelper.customizeButton('MuteToggle', {
    events: {
        'click': function(event) {
            // Custom click handler
            console.log('Mute button clicked', event);
        },
        'mouseenter': function() {
            // Hover state
            this.addClass('button-hover');
        },
        'mouseleave': function() {
            // Remove hover state
            this.removeClass('button-hover');
        }
    }
});
```

### Reset and Cleanup

```javascript
// Reset single button
vjsHelper.resetButton('PlayToggle');

// Reset all customizations
vjsHelper.resetAll();

// Clean up when done
vjsHelper.destroy();
```

## Real-World Examples

### Custom Quality Selector Implementation

```javascript
const qualityButton = vjsHelper.addCustomButton({
    name: 'QualitySelector',
    title: 'Video Quality',
    iconHTML: `
        <span class="quality-label">720p</span>
        <i class="fas fa-caret-down"></i>
    `,
    styles: {
        'root': {
            'display': 'flex',
            'align-items': 'center',
            'padding': '0 10px',
            'cursor': 'pointer'
        },
        '.quality-label': {
            'margin-right': '5px',
            'font-size': '14px'
        }
    },
    events: {
        click: function() {
            // Quality menu toggle logic
            const qualities = ['2160p', '1080p', '720p', '480p'];
            // Implementation details...
        }
    },
    position: {
        relativeTo: 'FullscreenToggle',
        index: -1
    }
});
```

### Custom Playback Speed Control

```javascript
const speedButton = vjsHelper.addCustomButton({
    name: 'PlaybackSpeed',
    title: 'Playback Speed',
    iconHTML: '<span class="speed-label">1x</span>',
    styles: {
        'root': {
            'min-width': '40px',
            'text-align': 'center'
        },
        '.speed-label': {
            'font-family': 'monospace',
            'font-weight': 'bold'
        }
    },
    events: {
        click: function() {
            const speeds = [0.5, 1, 1.5, 2];
            const currentSpeed = player.playbackRate();
            const currentIndex = speeds.indexOf(currentSpeed);
            const nextIndex = (currentIndex + 1) % speeds.length;
            player.playbackRate(speeds[nextIndex]);
            this.querySelector('.speed-label').textContent = speeds[nextIndex] + 'x';
        }
    }
});
```

## Common Pitfalls and Solutions

1. **Button Not Found**
   ```javascript
   // ❌ Wrong
   vjsHelper.customizeButton('nonexistentButton', {});
   
   // ✅ Right
   const button = vjsHelper.customizeButton('PlayToggle', {});
   if (button) {
       // Customization successful
   }
   ```

2. **Event Handler Context**
   ```javascript
   // ❌ Wrong
   events: {
       click: () => {
           this.player.play(); // 'this' is wrong
       }
   }
   
   // ✅ Right
   events: {
       click: function() {
           this.player_.play(); // 'this' is the button instance
       }
   }
   ```

## Best Practices

1. Always clean up when disposing of the player:
   ```javascript
   player.on('dispose', () => {
       vjsHelper.destroy();
   });
   ```

2. Use strict mode for better error detection:
   ```javascript
   const vjsHelper = new VjsPlayer(player, {
       strictMode: true
   });
   ```

3. Enable debug mode during development:
   ```javascript
   const vjsHelper = new VjsPlayer(player, {
       debug: true
   });
   ```

## License

MIT

## Contributing

Contributions are welcome! Please read our [contributing guidelines](CONTRIBUTING.md) before submitting pull requests.
