class InforDraggable extends HTMLElement{static callbacks={};constructor(){super();this.grabbed_item=null;this.grabbed_copy=null;this.offset_x=0;this.offset_y=0;this.container=null;this.movement_x_delta=0;this.movement_y_delta=0;this.appendStyle();this.onMouseDown=this.onMouseDown.bind(this);this.onMouseMove=this.onMouseMove.bind(this);this.onMouseUp=this.onMouseUp.bind(this)}
static get observedAttributes(){return['id','onchange','wire:onchange']}
connectedCallback(){if(!this.id){this.id='infor-draggable-'+Math.random().toString(36).substring(2,15)}
this.addEventListener('mousedown',this.onMouseDown)}
disconnectedCallback(){this.removeEventListener('mousedown',this.onMouseDown)}
onMouseDown(event){if(event.button!==0){return}
const no_drag=event.target.closest('[data-no-drag]');if(no_drag){const nested=event.target.closest('infor-draggable');if(!nested||nested===this){return}}
const item=event.target.closest('infor-draggable-item');if(!item){return}
const parent=item.parentElement;if(parent.tagName!=='INFOR-DRAGGABLE'||parent!==this){return}
event.preventDefault();event.stopPropagation();const container=parent
const rect=item.getBoundingClientRect();this.offset_x=event.clientX-rect.left;this.offset_y=event.clientY-rect.top;this.container=container;this.grabbed_item=item;document.addEventListener('mousemove',this.onMouseMove);document.addEventListener('mouseup',this.onMouseUp);this.current_values=this.values;this.createDraggableCopy()
this.updateDraggableCopyPosition(event)}
onMouseMove(event){this.setMoveDelta(event);this.updateDraggableCopyPosition(event);this.placeItemIntoBestPosition()}
onMouseUp(){document.removeEventListener('mousemove',this.onMouseMove);document.removeEventListener('mouseup',this.onMouseUp);this.destroyDraggableCopy();if(this.valuesChanged()){this.callback(this.values,this.id);this.onchange(this.values,this.id);this.livewireCallback(this.values,this.id)}}
appendStyle(){if(InforDraggable.style_appended){return}
InforDraggable.style_appended=!0;const style=document.createElement('style');style.textContent=`
infor-draggable{
position: relative;
display: flex;
flex-direction: column;
gap: .5rem;
}
infor-draggable-item{
display: block;
cursor: grab;
}
infor-draggable-item [data-no-drag] {
cursor: default;
}
`;document.head.appendChild(style)}
get values(){return this.items.map(el=>el.value)}
get items(){return Array.from(this.children).filter(el=>{return el.tagName==='INFOR-DRAGGABLE-ITEM'&&!el.hasAttribute('data-copy')})}
set current_values(values){this._current_values=values}
get current_values(){return this._current_values}
valuesChanged(){return JSON.stringify(this.current_values)!==JSON.stringify(this.values)}
get id(){return this.getAttribute('id')}
set id(id){this.setAttribute('id',id)}
get callback(){return InforDraggable.callbacks[this.id]||((values,id)=>{})}
get onchange(){const onchange=this.getAttribute('onchange');if(!onchange||typeof window[onchange]!=='function'){return(values)=>{}}
return window[onchange]}
get livewireCallback(){const onchange=this.getAttribute('wire:onchange');if(!window.Livewire||!onchange){return(values)=>{}}
return(values,id)=>{window.Livewire.emit(onchange,values,id)}}
setMoveDelta(event){this.movement_x_delta=event.movementX;this.movement_y_delta=event.movementY}
createDraggableCopy(){const copy=this.grabbed_item.cloneNode(!0);const rect=this.grabbed_item.getBoundingClientRect();const width=rect.width;const height=rect.height;copy.style.position='absolute';copy.style.width=`${width}px`;copy.style.height=`${height}px`;copy.style.cursor='grabbing';copy.setAttribute('data-copy','true');this.container.appendChild(copy);this.grabbed_copy=copy;this.grabbed_item.style.opacity='0'}
destroyDraggableCopy(){this.grabbed_copy.remove();this.grabbed_copy=null;this.grabbed_item.style.opacity='1'}
updateDraggableCopyPosition(event){const container_rect=this.container.getBoundingClientRect();const container_left=container_rect.left+window.scrollX;const container_top=container_rect.top+window.scrollY;const container_width=this.container.clientWidth;const container_height=this.container.clientHeight;const container_style=getComputedStyle(this.container);const container_padding_left=parseFloat(container_style.paddingLeft);const container_padding_top=parseFloat(container_style.paddingTop);const item_rect=this.grabbed_item.getBoundingClientRect();const item_width=item_rect.width;const item_height=item_rect.height;let x=event.pageX-container_left-this.offset_x;let y=event.pageY-container_top-this.offset_y;if(x+item_width>container_width+container_padding_left){x=container_width-item_width+container_padding_left}else if(xcontainer_height+container_padding_top){y=container_height-item_height+container_padding_top}else if(yel!==this.grabbed_item);const copy_bounding_rect=this.grabbed_copy.getBoundingClientRect();if(this.movement_y_delta<0){items=items.reverse()}
items.forEach((item,index)=>{const item_bounding_rect=item.getBoundingClientRect();const distance_below=Math.abs(copy_bounding_rect.bottom-item_bounding_rect.top);const distance_above=Math.abs(copy_bounding_rect.top-item_bounding_rect.bottom);if(this.movement_y_delta>0&©_bounding_rect.bottom>item_bounding_rect.top&&distance_below>5){item.after(this.grabbed_item)}
if(this.movement_y_delta<0&©_bounding_rect.top5){item.before(this.grabbed_item)}})}
static onChange(id,callback){InforDraggable.callbacks[id]=callback}
static values(id){return document.getElementById(id).values}}
class InforDraggableItem extends HTMLElement{constructor(){super()}
static get observedAttributes(){return['value']}
get value(){return this.getAttribute('value')}
set value(val){this.setAttribute('value',val)}}
customElements.define('infor-draggable',InforDraggable);customElements.define('infor-draggable-item',InforDraggableItem)