/*
 * Copyright 2007 nori090
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package lib2chj.util;

import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import lib2chj.struct.Category;
import lib2chj.struct.HTTP_DATA;
import lib2chj.struct.Ita;
import lib2chj.util.html.HtmlException;
import lib2chj.util.html.HtmlHandler;
import lib2chj.util.html.HtmlParser;
import lib2chj.util.html.Tag;

/**
 * http://menu.2ch.net/bbsmenu.html
 * 
 * @author nori090
 * @version $Rev: 19 $ $Date: 2008-03-25 22:46:11 +0900 (Tue, 25 Mar 2008) $
 */
public class BbsMenu {
    static Set<Category> categorys;

    private BbsMenu() {
        super();
    }

    public static Set<Category> getCategorys() {
        return categorys;
    }

    static {
        build();
    }

    static void build() {
        try {
            final String bbsmenu = "http://menu.2ch.net/bbsmenu.html";
            Set<Category> set = new LinkedHashSet<Category>();
            HTTP_DATA data = new HTTP_DATA().setUrl( bbsmenu );
            HttpURLConnection con = HttpHelper.createConnection( data );
            HtmlParser p = new HtmlParser();
            Handler h = new Handler();
            p.parse( con.getInputStream(), h );
            categorys = Collections.unmodifiableSet( filter( set, h.list ) );
        }
        catch ( Exception e ) {
            e.printStackTrace();
            throw new RuntimeException( e );
        }
    }

    static Set<Category> filter( Set<Category> set, List<Property> list ) {
        Category c = null;
        boolean skip = false;
        for ( Property p : list ) {
            if ( p.k == Property.KEY.CATEGORY ) {
                String data = (String) p.data;
                if ( "特別企画".equals( data ) || "ツール類".equals( data ) || "チャット".equals( data ) || "運営案内".equals( data ) ) {
                    skip = true;
                    continue;
                }
                if ( "まちＢＢＳ".equals( data ) ) {
                    break;
                }
                skip = false;
                c = new Category();
                c.setCategory( data );
                set.add( c );
            }
            else if ( p.k == Property.KEY.NAME ) {
                if ( !skip ) {
                    if ( null == c.getItaMap() ) {
                        c.setItaMap( new LinkedHashMap<String, Ita>() );
                    }
                    Ita ita = (Ita) p.data;
                    try {
                        URL url = new URL( ita.getUrl() );
                        if ( "/".equals( url.getPath() ) ) {
                            // 板名がないurlは除外
                            continue;
                        }
                        ita.setItaName( HttpHelper._split_ita_name_at_path( url.getPath() ) );
                    }
                    catch ( MalformedURLException e ) {
                        e.printStackTrace();
                        throw new RuntimeException( e );
                    }

                    Ita src = c.getIta( ita.getItaName() );
                    if ( null == src ) {
                        c.putIta( ita );
                    }
                    else {
                        src.setItaName_ja( ita.getItaName_ja() );
                        src.setUrl( ita.getUrl() );
                    }
                }
            }
            else {
                throw new RuntimeException( "unknown key" );
            }
        }
        return set;
    }

    public static void main( String[] args ) {
    }

    static class Property {
        enum KEY {
            CATEGORY, NAME;
        }

        KEY k;

        Object data;
    }

    static class Handler
        implements HtmlHandler {
        boolean firstBtag = false;

        boolean btag = false;

        boolean atag = false;

        ArrayList<Property> list = new ArrayList<Property>();

        Property tmp;

        Ita ita;

        @Override
        public void startDocument()
            throws HtmlException {
            firstBtag = false;
            btag = false;
            atag = false;
        }

        @Override
        public void endDocument()
            throws HtmlException {
            firstBtag = false;
            btag = false;
            atag = false;
        }

        @Override
        public void content( String data )
            throws HtmlException {
            if ( firstBtag ) {
                if ( atag ) {
                    ita.setItaName_ja( data );
                    list.add( tmp );
                }
                if ( btag ) {
                    tmp = new Property();
                    tmp.k = Property.KEY.CATEGORY;
                    tmp.data = data;
                    list.add( tmp );
                }
            }
        }

        @Override
        public void startTag( Tag tag )
            throws HtmlException {
            if ( firstBtag ) {
                if ( Tag.A.equals( tag.getType() ) ) {
                    tmp = new Property();
                    tmp.k = Property.KEY.NAME;
                    ita = new Ita( null );
                    ita.setUrl( tag.getAttribute( Tag.ATTR_HREF ) );
                    tmp.data = ita;
                }
            }
            if ( Tag.B.equals( tag.getType() ) ) {
                if ( firstBtag == false ) {
                    firstBtag = true;
                }
                btag = true;
            }
            if ( Tag.A.equals( tag.getType() ) ) {
                atag = true;
            }
        }

        @Override
        public void endTag( Tag tag )
            throws HtmlException {
            if ( Tag.A.equals( tag.getType() ) ) {
                atag = false;

            }
            if ( Tag.B.equals( tag.getType() ) ) {
                btag = false;
            }
        }
    }
}
